I am consuming Rest API and wants to save User Data, i am able to hit the API but not able to send the object. Its showing null in API.
I checked my console and network, its showing the angular application URL not the API URL.
export class UserService {
url = 'http://localhost:8085/api/employees';
constructor(private http: HttpClient) {}
userData(user: User): Observable<any> {
const params = new HttpParams().set('id', '5').
set('userName', 'Bisnu').set('salary', '100').set('department', 'IT').set('password', 'mohan')
.set('firstName', 'Bisnu').set('lastName', 'Biswal');
const newUser = {
userName: 'Bisnu',
salary: 100,
password: 'mohan',
department: 'IT',
firstName: 'Bisnu',
lastName: 'Mohan'
};
console.log(newUser);
console.log(this.url);
return this.http.post<any>(this.url, newUser);
}
}
and from component i am calling this service
onSubmit(){
console.log(this.user);
this.userService.userData(this.user).subscribe(
data => console.log("success", data),
error => console.error("Error!",error)
);
this.resetForm();
}
}
Browser console i checked it is as below, which is wrong.
the controller is as below
The User model is as below
Try this, backend object and your newuser object does not match.
userData(user: User): Observable<any> {
user.Id :1;
user.userName: 'Bisnu';
user.salary: 100;
user.password: 'mohan';
user.department: 'IT';
user.firstName: 'Bisnu';
user.lastName: 'Mohan';
return this.http.post<any>(this.url, user);
}
Related
I have a protected resource on Keycloak created via remote API with this code:
private fun ProtectedEntity.protect(location: URI, principal: Principal) {
val newResource = ResourceRepresentation()
newResource.name = this.id
newResource.displayName = this.name
newResource.type = "urn:$appName:resources:${this.javaClass.simpleName.toLowerCase().replace("entity", "")}"
newResource.owner = ResourceOwnerRepresentation(this.creator)
newResource.ownerManagedAccess = true
newResource.uris = setOf(location.path.toString())
authzClient.protection().resource().create(newResource)
}
The resource owner is the user who invoked the method and he can manage his own resources.
Now I have to check if a user has permission to access a resource and if not, I guess I should return a ticket in the case the user would like request access to the resource. I tried with this but authorize() throws "Error creating permission ticket".
override fun read(id: ID, principal: Principal): Mono<ResponseEntity<E>> {
val currentUserToken = principal!!.getCurrentUserToken()
val resource = authzClient.protection().resource().findByName(id.toString(), currentUserToken.getUsername())
val token = currentUserToken.tokenValue
val request = AuthorizationRequest()
request.addPermission(resource.id)
request.setRpt(token)
// This returns Error creating permission ticket !?
val response = authzClient.authorization().authorize(request)
val result = authzClient.protection().introspectRequestingPartyToken(response.token)
println(result.active)
if (result.active) {
return super.read(id, principal)
} else throw RuntimeException("Result token RPT is not active!")
}
How I would delegate on Keycloak permission evaluating using authzClient?
The solution is to replace .findByName() by .findByUri(). This endpoint not take into account the resource's owner. I created a gist just in case someone else may need it: ResourceAccessKeycloakWebFilter
i have an angular basic project and a simple microservice jhipster project. since i chosed jwt option in my jhipster project , i want to consume methods from my angular project.after looking for hours i finnaly found this code which helped me to connect successfuly but i get a weird error which bloked me. here is my angular classes i used to try connect and consume jhipster methods:
auth-interceptor.ts file
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private token: TokenStorageService) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
let authReq = req;
const token = this.token.getToken();
if (token != null) {
authReq = req.clone({ headers: req.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token) });
}
return next.handle(authReq);
}
}
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
];
auth.service.ts
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
#Injectable({
providedIn: 'root'
})
export class AuthService {
private loginUrl = 'http://localhost:8082/api/authenticate';
private signupUrl = 'http://localhost:8080/api/auth/signup';
constructor(private http: HttpClient) {
}
attemptAuth(credentials: AuthLoginInfo): Observable<JwtResponse> {
return this.http.post<JwtResponse>(this.loginUrl, credentials, httpOptions);
}
signUp(info: SignUpInfo): Observable<string> {
return this.http.post<string>(this.signupUrl, info, httpOptions);
}
}
jwt-response.ts
export class JwtResponse {
accessToken: string;
type: string;
username: string;
authorities: string[];
}
token-storage.service.spec.ts
describe('TokenStorageService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [TokenStorageService]
});
});
it('should be created', inject([TokenStorageService], (service: TokenStorageService) => {
expect(service).toBeTruthy();
}));
});
token.storage.service.ts
const TOKEN_KEY = 'AuthToken';
const USERNAME_KEY = 'AuthUsername';
const AUTHORITIES_KEY = 'AuthAuthorities';
#Injectable({
providedIn: 'root'
})
export class TokenStorageService {
private roles: Array<string> = [];
constructor() { }
signOut() {
window.sessionStorage.clear();
}
public saveToken(token: string) {
window.sessionStorage.removeItem(TOKEN_KEY);
window.sessionStorage.setItem(TOKEN_KEY, token);
}
public getToken(): string {
return sessionStorage.getItem(TOKEN_KEY);
}
public saveUsername(username: string) {
window.sessionStorage.removeItem(USERNAME_KEY);
window.sessionStorage.setItem(USERNAME_KEY, username);
}
public getUsername(): string {
return sessionStorage.getItem(USERNAME_KEY);
}
public saveAuthorities(authorities: string[]) {
window.sessionStorage.removeItem(AUTHORITIES_KEY);
window.sessionStorage.setItem(AUTHORITIES_KEY, JSON.stringify(authorities));
}
public getAuthorities(): string[] {
this.roles = [];
if (sessionStorage.getItem(TOKEN_KEY)) {
JSON.parse(sessionStorage.getItem(AUTHORITIES_KEY)).forEach(authority => {
this.roles.push(authority.authority);
});
}
return this.roles;
}
}
and finnaly this is my connection method:
onSubmit() {
console.log(this.form);
this.loginInfo = new AuthLoginInfo(
this.form.username,
this.form.password);
this.authService.attemptAuth(this.loginInfo).subscribe(
data => {
this.tokenStorage.saveToken(data.accessToken);
this.tokenStorage.saveUsername(data.username);
this.tokenStorage.saveAuthorities(data.authorities);
this.isLoginFailed = false;
this.isLoggedIn = true;
this.roles = this.tokenStorage.getAuthorities();
this.reloadPage();
},
error => {
console.log(error);
this.errorMessage = error.error.message;
this.isLoginFailed = true;
}
);
}
with this i am able to login successfully but once i login i get this error when i try to do anything else:
core.js:6014 ERROR SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at TokenStorageService.getAuthorities (token-storage.service.ts:45)
Guys if u know any simple method to connect to jhipster using jwt from angular please help me cause i am blocked here , i have a full jhipster project which i cant consume any..
Well, seems your server does not provide authorities in the JWT response. Since the data is missing, the saveAuthorities saves string "undefined" that cannot be served later.
If the reason authorities is missing is that you blindly copied some random code off the internet, delete the authorities from class JwtResponse and saveAuthorities, getAuthorities and all references to them.
Otherwise, just provide the authorities in your response.
Or you can check if authorities exist when saving them in onSubmit callback.
if (data.authorities)
this.tokenStorage.saveAuthorities(data.authorities);
You have a typo in your condition in the getAuthorities method. The token is undefined. The error you have comes from trying to parse undefined in JSON.parse(...). You check the TOKEN_KEY in storage but read AUTHORITIES_KEY
Your code:
if (sessionStorage.getItem(TOKEN_KEY)) {
JSON.parse(sessionStorage.getItem(AUTHORITIES_KEY)).forEach(authority => {
Correct code:
if (sessionStorage.getItem(AUTHORITIES_KEY)) {
JSON.parse(sessionStorage.getItem(AUTHORITIES_KEY)).forEach(authority => {
I have a web app which is secured with JWT. How to make it remember my login data and not to enter it all again if I open a new tab? I use axios.post to the authenticate endpoint and save the token in localStorage
My code of the authentication service in frontend:
import axios from 'axios'
const API_URL = 'http://localhost:8080/map-runner'
export const USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser'
class AuthenticationService {
executeJwtAuthenticationService(username, password) {
return axios.post(`${API_URL}/authenticate`, {
username,
password
})
}
registerSuccessfulLoginForJwt(username, token) {
sessionStorage.setItem(USER_NAME_SESSION_ATTRIBUTE_NAME, username)
localStorage.setItem("token", token)
}
createJWTToken(token) {
return 'Bearer ' + token
}
logout() {
sessionStorage.removeItem(USER_NAME_SESSION_ATTRIBUTE_NAME);
}
isUserLoggedIn() {
let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME)
if (user === null) return false
return true
}
getLoggedInUserName() {
let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME)
if (user === null) return ''
return user
}
setupAxiosInterceptors(token) {
axios.interceptors.request.use(
(config) => {
if (this.isUserLoggedIn()) {
config.headers.authorization = token
}
return config
}
)
}
}
export default new AuthenticationService()
Now my Login Component:
import React, { Component } from 'react'
import AuthenticationService from '../service/AuthenticationService';
class LoginComponent extends Component {
constructor(props) {
super(props)
this.state = {
username: '',
password: '',
hasLoginFailed: false,
showSuccessMessage: false
}
}
handleChange = (event) => {
this.setState(
{
[event.target.name]
: event.target.value
}
)
}
loginClicked = () => {
AuthenticationService
.executeJwtAuthenticationService(this.state.username, this.state.password)
.then((response) => {
AuthenticationService.registerSuccessfulLoginForJwt(this.state.username, response.data.token)
console.log(response.data.token);
this.props.history.push(`/calculations`)
}).catch(() => {
this.setState({ showSuccessMessage: false })
this.setState({ hasLoginFailed: true })
})
}
render() {
return (
<div>
<h1>Вход</h1>
<div className="container">
{this.state.hasLoginFailed && <div className="alert alert-warning">Неверные данные</div>}
{this.state.showSuccessMessage && <div>Вход выполнен успешно</div>}
Имя пользователя: <input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
Пароль: <input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
<button className="btn btn-success" onClick={this.loginClicked}>Вход</button>
</div>
</div>
)
}
}
export default LoginComponent
The backend in spring boot is quite long even regarding the JWT part, so I guess I'll leave the link to the tutorial which was the basis of my backend. The paths are a bit different but in general these backend parts are the same.. I also tried to use sessionstorage instead of localstorage, doesnt work. If possible, maybe we can test everything out firstly replicating the whole tutorial code as the jwt part is almost the same there (I have a copy and they have a link to their github in the article)
You must be having login page where you would be sending jwt token at the time of login so
store the jwt token at the time if login as
axios.post("http:yourAPIaddresshere", formData)
.then((response) => {
if(response.status === 200) {
// storing session
localStorage.setItem('session', response.data.token)
this.props.history.push('home');
} else {
this.showMessage('Error message', "Please check your credentials.")
}
}
});
}
This is where your session is stored in localStorage now in other all the files retrieve the token
In same login file also do :
componentDidMount(){
if (localStorage.getItem('session') !== null) {
this.props.history.push('home')
}
}
this will always push your navigation to other tabs.
To make your other tabs/pages secure also check session if not null it won't let you open other pages using routes without session token
componentDidMount(){
if (localStorage.getItem('session') === null)
this.props.history.push('login') }
P.S: Make sure to empty the sesion token at the time of logout as :
localStorage.removeItem('session');
You can save the token either in local storage or cookie. And every-time you send any xhr request you can pass the token in the header.
My days of Java web development now lie about 6 years behind me and despite my hectic new life as a non-technical consultant I want to get back in to the tech world and equip myself with some essential web dev skills.
To get me started, I installed a vagrant box using this tutorial:
https://dzone.com/articles/vagrant
... which worked like a treat and got me my Ubuntu box on my Windows host machine up and running in no time. Also it comes with Java 7 and the Tomcat app server that I'm still quite familiar with from past days. Notwithstanding the fact that there are probably better servers out there to practice on, this one works and I'll use it for my tinkering for now. The example web app that came with the tutorial also works, so I'm confident that my Tomcat is running on the guest machine on port 8080.
The next step was to find a good AngularJS and Spring MVC tutorial. Again, while I know that AngularJS is the latest craze in web dev, Spring MVC may be somewhat outdated (?) but since I'm a Java-boy since I hatched from the Uni-egg I wouldn't mind going with it for now.
The tutorial I found is this one:
http://websystique.com/springmvc/spring-mvc-4-angularjs-example/
I downloaded the project from git and deployed it into my tomcat webapps folder. In the user_service.js file I left the REST_SERVICE_URI as http://localhost:8080/Spring4MVCAngularJSExample/user/ given that Tomcat runs on port 8080 on the host Ubuntu box and I can access the application on my guest machine in the browser at http://192.168.33.10:8080/Spring4MVCAngularJSExample
The problem is that the application (while it's showing up in the browser), does not load the mock-users that are populated in the UserServiceImpl class and that should show up when loading the app. When I check my Firefox console under the JavaScript tab, I get the 'Error while fetching Users' error message from the fetchAllUsers function in the user_controller.js script.
I suspect that the problem here is that the front-end (AngularJS $http service) cannot contact the back-end (Spring service). If there were no users in the back-end and returned 0, I wouldn't get the error but an empty set instead, hence my suspicion of some other problem.
My question is how to debug this web app from here? I have tried to look through the front-end console logs using the FF Developer tool (Debugger) and I must admit I haven't written any JUnit test to actually run a test against the Spring service implementation class.
Thanks for your advice, and let me know if I should provide any more details.
Cheers
AHL
Spring controller:
package com.websystique.springmvc.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import com.websystique.springmvc.model.User;
import com.websystique.springmvc.service.UserService;
#RestController
public class HelloWorldRestController {
#Autowired
UserService userService; //Service which will do all data retrieval/manipulation work
//-------------------Retrieve All Users--------------------------------------------------------
#RequestMapping(value = "/user/", method = RequestMethod.GET)
public ResponseEntity<List<User>> listAllUsers() {
List<User> users = userService.findAllUsers();
if(users.isEmpty()){
return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
}
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}
//-------------------Retrieve Single User--------------------------------------------------------
#RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> getUser(#PathVariable("id") long id) {
System.out.println("Fetching User with id " + id);
User user = userService.findById(id);
if (user == null) {
System.out.println("User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
//-------------------Create a User--------------------------------------------------------
#RequestMapping(value = "/user/", method = RequestMethod.POST)
public ResponseEntity<Void> createUser(#RequestBody User user, UriComponentsBuilder ucBuilder) {
System.out.println("Creating User " + user.getUsername());
if (userService.isUserExist(user)) {
System.out.println("A User with name " + user.getUsername() + " already exist");
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
userService.saveUser(user);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
//------------------- Update a User --------------------------------------------------------
#RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
public ResponseEntity<User> updateUser(#PathVariable("id") long id, #RequestBody User user) {
System.out.println("Updating User " + id);
User currentUser = userService.findById(id);
if (currentUser==null) {
System.out.println("User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
currentUser.setUsername(user.getUsername());
currentUser.setAddress(user.getAddress());
currentUser.setEmail(user.getEmail());
userService.updateUser(currentUser);
return new ResponseEntity<User>(currentUser, HttpStatus.OK);
}
//------------------- Delete a User --------------------------------------------------------
#RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
public ResponseEntity<User> deleteUser(#PathVariable("id") long id) {
System.out.println("Fetching & Deleting User with id " + id);
User user = userService.findById(id);
if (user == null) {
System.out.println("Unable to delete. User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
userService.deleteUserById(id);
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
//------------------- Delete All Users --------------------------------------------------------
#RequestMapping(value = "/user/", method = RequestMethod.DELETE)
public ResponseEntity<User> deleteAllUsers() {
System.out.println("Deleting All Users");
userService.deleteAllUsers();
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
}
IndexController.java:
package com.websystique.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/")
public class IndexController {
#RequestMapping(method = RequestMethod.GET)
public String getIndexPage() {
return "UserManagement";
}
}
Javascript user_controller.js:
'use strict';
angular.module('myApp').controller('UserController', ['$scope', 'UserService', function($scope, UserService) {
var self = this;
self.user={id:null,username:'',address:'',email:''};
self.users=[];
self.submit = submit;
self.edit = edit;
self.remove = remove;
self.reset = reset;
fetchAllUsers();
function fetchAllUsers(){
UserService.fetchAllUsers()
.then(
function(d) {
self.users = d;
},
function(errResponse){
console.error('Error while fetching Users');
}
);
}
function createUser(user){
UserService.createUser(user)
.then(
fetchAllUsers,
function(errResponse){
console.error('Error while creating User');
}
);
}
function updateUser(user, id){
UserService.updateUser(user, id)
.then(
fetchAllUsers,
function(errResponse){
console.error('Error while updating User');
}
);
}
function deleteUser(id){
UserService.deleteUser(id)
.then(
fetchAllUsers,
function(errResponse){
console.error('Error while deleting User');
}
);
}
function submit() {
if(self.user.id===null){
console.log('Saving New User', self.user);
createUser(self.user);
}else{
updateUser(self.user, self.user.id);
console.log('User updated with id ', self.user.id);
}
reset();
}
function edit(id){
console.log('id to be edited', id);
for(var i = 0; i < self.users.length; i++){
if(self.users[i].id === id) {
self.user = angular.copy(self.users[i]);
break;
}
}
}
function remove(id){
console.log('id to be deleted', id);
if(self.user.id === id) {//clean form if the user to be deleted is shown there.
reset();
}
deleteUser(id);
}
function reset(){
self.user={id:null,username:'',address:'',email:''};
$scope.myForm.$setPristine(); //reset Form
}
}]);
Javascript user_service.js:
'use strict';
angular.module('myApp').factory('UserService', ['$http', '$q', function($http, $q){
var REST_SERVICE_URI = 'http://localhost:8080/Spring4MVCAngularJSExample/user/';
var factory = {
fetchAllUsers: fetchAllUsers,
createUser: createUser,
updateUser:updateUser,
deleteUser:deleteUser
};
return factory;
function fetchAllUsers() {
var deferred = $q.defer();
$http.get(REST_SERVICE_URI)
.then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while fetching Users');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
function createUser(user) {
var deferred = $q.defer();
$http.post(REST_SERVICE_URI, user)
.then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while creating User');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
function updateUser(user, id) {
var deferred = $q.defer();
$http.put(REST_SERVICE_URI+id, user)
.then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while updating User');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
function deleteUser(id) {
var deferred = $q.defer();
$http.delete(REST_SERVICE_URI+id)
.then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while deleting User');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
}]);
On the server (the vagrant host machine), I can wget the URL and get my data back from the Spring server:
vagrant#precise32:~$ wget http://localhost:8080/Spring4MVCAngularJSExample/user/--2016-08-26 11:08:24-- http://localhost:8080/Spring4MVCAngularJSExample/user/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/json]
Saving to: `index.html'
[ <=> ] 206 --.-K/s in 0s
2016-08-26 11:08:24 (9.77 MB/s) - `index.html' saved [206]
vagrant#precise32:~$ less index.html
this gives me the expected result set:
[{"id":1,"username":"Sam","address":"NY","email":"sam#abc.com"},{"id":2,"username":"Tomy","address":"ALBAMA","email":"tomy#abc.com"},{"id":3,"username":"Kelly","address":"NEBRASKA","email":"kelly#abc.com"}]
From your spring controller code all your request mappings are expecting user in the url so if you don't have this the spring controllers will not be called. Is you dispatcher servlet set up to except all http requests E.g /
The problem was a simple mistake:
In the user_service.js file, the REST_SERVICE_URI must be set to the address of the host machine:
http://192.168.33.10:8080/Spring4MVCAngularJSExample/user/
So, when deploying this to a (remote) server, I suppose the 192.168.33.10:8080 portion would need to be changed to that server's IP and the respective Tomcat port.
My problem existed (probably) because I was using a virtual box and had (mistakenly) used the host machine's IP instead of the guest machine's IP. Please correct me if I'm wrong, I'm still somewhat confused ....
I have a web application with HTML / jQuery which ic connected with AJAX / JSON to a backend system with Java EE / Spring MVC.
In the frontend, a Person can be created by fill in the form fields and then it is submitted and this jQuery code executed:
var person = $(this).serializeObject();
$.postJSON("add/", person, function(data) {
alert("Person with ID "+data.person.id+"' added successfully");
});
In the best case, the Person is created and I'll get a Person object and I can access the values with data.person.*.
Now I want to validate the data which is sent to the backend system and in a case of an error, I want to display in the first step an alert error message.
I did this in the backend system:
#RequestMapping(value="add/", method=RequestMethod.POST)
public #ResponseBody Map<String, ? extends Object> addPerson(#RequestBody Person p, HttpServletResponse response) {
Set<ConstraintViolation<Person>> failures = validator.validate(p);
if (!failures.isEmpty()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return validationMessages(failures);
} else {
Person person = this.personService.addPerson(p);
return Collections.singletonMap("person", new SerialPerson(person.getId(), person.getName(), ...));
}
}
// internal helpers
private Map<String, String> validationMessages(Set<ConstraintViolation<Person>> failures) {
Map<String, String> failureMessages = new HashMap<String, String>();
for (ConstraintViolation<Person> failure : failures) {
failureMessages.put(failure.getPropertyPath().toString(), failure.getMessage());
System.out.println(failure.getPropertyPath().toString()+" - "+failure.getMessage());
}
return failureMessages;
}
My Person object is annotated, and I get the System.out.println(failure.getPropertyPath().toString()+" - "+failure.getMessage()); on the console, that for example, "name - must be between 1-30 chars"
But how can create an alert message in jQuery in the frontend system?
Thank you in advance for your help & Best Regards.
Update: Link to the Spring MVC AJAX example, where I found the validationMessages method. But there is also no solution how to get the error message.
SOLUTION:
I have to call:
jQuery.ajax({
'type': 'POST',
'url': "add/",
'contentType': 'application/json',
'data': JSON.stringify(person),
'dataType': 'json',
'success': function(data) {alert("success");},
'error': function(xhr) {alert(xhr.responseText);}
});
You can do something like this:
var person = $(this).serializeObject();
$.postJSON("add/", person, function(data) {
if(data.person) {
alert("Person with ID "+data.person.id+"' added successfully");
}
else {
var errors = "";
for(var key in data) if(data.hasOwnProperty(key)) {
errors += data[key] + "\n";
}
alert(errors);
}
});
You shouldn't need to send back a bad request either. Is this what you want?
UPDATE
You can use the code shown in Spring Source, but you'd have to use jQuery.ajax
jQuery.ajax({
type: 'POST',
url: "add/",
data: person,
dataType: "json",
success: function(data) {
alert("Person with ID "+data.person.id+"' added successfully");
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
var errorJSON = JSON.parse(XMLHttpRequest.responseText); //if this is JSON otherwise just alerting XMLHttpRequest.responseText will do
var errors = "";
for(var key in errorJSON) if(errorJSON.hasOwnProperty(key)) {
errors += errorJSON[key] + "\n";
}
alert(errors);
}
});