AJAX request sending null parameter to Java Spring controller - java

I am trying to do a simple POST request but for some reason my Integer parameter is null. This is something so basic, but I don't see what I am doing wrong here.
Here is what I have tried so far:
$rootScope.addUser = function(userId) {
$http.post('/addUser', {
params: {
user_id: userId
}
}).then(function(result) {
$rootScope.userId = undefined;
});
};
Controller
#PostMapping("/addUser")
public void addTournament(#RequestParam(required = false) final Integer userId) {
LOG.info("addUser: {}" , userId);
}
I have also tried doing #RequestParam(name = "user_id") final Integer userId, but even that does not work either!
In the end I will removed the 'required = false' parameter, but I left it there for now just to verify that the userId is indeed null.
The input is being grabbed from the user they input a number and click a button.

The #RequestParam name does not match with the name of the attribute posted: user_id vs userId. Use #RequestParam(name = "user_id") final Integer userId to match them, or use the same request attribute and #RequestParam name.
[edit]
When I read params: { ... } I expected them to be additional request parameters instead of being part of the POST body. Could you try POSTing the data using:
$http.post('/addUser', { userId: userId }
And using the following #PostMapping:
#PostMapping("/addUser")
public void addTournament(#RequestBody User user) {
LOG.info("addUser: {}" , user.getUserId());
}
...
class User {
private String userId;
// getter and setter
}

Related

How do i differentiate between two endpoints, each with one PathVariable?

I'm working on a Spring Boot application. I have the following REST endpoint(s):
#GetMapping(value = { "/person/{name}", "/person/{age}" })
public PersonData getPersonData(#PathVariable(required = false) String name,
#PathVariable(required = false) Integer age) {
}
This endpoint can be called with either a name variable or an age variable, however it looks like it can't differentiate between them. If I was to call '.../person/20', it would not call "/person/{age}", but it always calls "/person/{name}".
I know I could make something like:
#GetMapping(value = { "/person/name/{name}", "/person/age/{age}" })
However are there any other way to solve it without adding anything to the path?
A path variable is something like a primary key usually.
Like:
/person/{id}
What you try is to search for data and this should be done with query parameters.
Example:
#GetMapping(value = { "/person/{name}", "/person/{age}" })
public PersonData getPersonData(#RequestParam String name,
#RequestParam Integer age) {
}
Then you can call it
/person?age=40
/person?name=Peter
age and name are logically not the same thing; the chosen best answer correctly suggests to keep them as distinguished parameters.
However you can check if the value is numeric and treat it like an age,
#GetMapping("/person/{value}")
public String getPerson(#PathVariable String value) {
if (value.matches("[0-9]|[0-9][0-9]"))
return "Age";
else
return "Name";
}
but this is ambiguous and error prone (e.g. how'll you distinguish when adding other numerical params like shoeSize or numberOfPartners?).
In your case I would make 2 different endpoints to be more clear, each one requiring it's own query parameter to be served.
#GetMapping(value = "/person")
public PersonData getPersonDataByName(#RequestParam(required = true) String name) {
....
}
#GetMapping(value = "/person")
public PersonData getPersonDataByAge(#RequestParam(required = true) Integer age) {
....
}
required = true can be omitted from the annotation as this is the default value, I used it just to point that each endpoint will be fulfilled only for that specific query parameter

Is it possible to verify empty input from the user in spring boot?

I'm writing a spring boot application and I'm having some troubles in verifying empty input from the user.
Is there a way to validate an empty input from the user?
For example:
#PostMapping("/new_post/{id}")
public int addNewPost(#PathVariable("id") Integer id, #RequestBody Post post) {
return postService.addNewPost(id, post);
}`
Here I want to add a new post only if the user exists in the database but when I send this post request I am getting the regular 404 error message and I am not able to provide my own exception although in my code I validate if the id equals to null.
http://localhost:8080/new_post/
Any idea what can I do?
Thanks
You can do something like this
#PostMapping(value = {"/new_post/{id}", "/new_post"})
public int addNewPost(#PathVariable(required = false, name="id") Integer id, #RequestBody Post post) {
return postService.addNewPost(id, post);
}
But the ideal way to handle this is using #RequestParam. #RequestParam is meant exactly for this purpose.
I think you need to do it like this:
#PostMapping(value = {"/new_post/", "/new_post/{id}"})
public int addNewPost(#PathVariable(value = "id", required = false) Integer id, #RequestBody Post post) {
This way you are also handling the URL when ID is null
I Think This is a Better Answer for Two Others :
#PostMapping("/new_post/{id}")
public int addNewPost(#PathVariable("id") Integer id, #RequestBody Post post)
{
if(!ObjectUtils.isEmpty(post))
{
return postService.addNewPost(id, post);
}
else
return null; // You can throws an Exception or any others response
}
id : Not required to check 'id', because with out id the requested method is not call.

cannot perform edit operation in spring boot

I want to edit my User Class while passing the id and while returning user object to controller it is getting error such as "There was an unexpected error (type=Internal Server Error, status=500)".It is telling me to typecast to Optional.I don't know what to do.
UserService Class
public User editMyUser(int id) {
return userRepository.findById(id);
}
Controller Class
#RequestMapping("/edit-user")
public String editUser(#RequestParam int id, HttpServletRequest request) {
userService.deleteMyUser(id);
request.setAttribute("user", userService.editMyUser(id));
request.setAttribute("mode", "MODE_UPDATE");
return "welcome";
}
This is how findById looks like in the new version of Spring (according to docs):
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
Optional<T> findById(ID primaryKey);
// .... other methods ...
}
So, the first thing I would change in your code is :
public Optional<User> editMyUser(int id) {
return userRepository.findById(id);
}
Make your method return Optional<User>, maybe this will help.
Also, be careful when using user returned by that new method, e.g. here
request.setAttribute("user", userService.editMyUser(id));
With Optional you need to use get() to obtain the actual user instance:
userService.editMyUser(id).get()
but first, you should check if that Optional actually contains the user:
Optional<User> optionalUser = userService.editMyUser(id);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
// do whatever you need
} else {
// means user is null - nothing found for ID
// act accordingly
}
There is also a good documentation that Spring provides. Could be useful.
Happy Coding :)
I let u here the cofiguration of the interface for a rest service that is working rihg now
#Api(value = "empleados", description = "the empleados API")
public interface EmpleadosApi {
#ApiOperation(value = "Buscar empleados", notes = "", response = ResultadoBusquedaEmpleado.class, tags = {})
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Búsqueda de empleados", response = ResultadoBusquedaEmpleado.class) })
#RequestMapping(value = "/empleados", method = RequestMethod.GET)
ResponseEntity<ResultadoBusquedaEmpleado> empleadosGet(
#ApiParam(value = "Nombre de empleado") #RequestParam(value = "nombre", required = false) String nombre)
}

Spring MVC request mapping - full request URI

When creating or listing and item using REST api I return also the whole resource path.
For example creating a person record returns http://service:9000/person/1234in response. In order to get schema, host & port part like http://service:9000, I extract it from URL obtained by HttpServletRequest.getRequestURL().
Example (not the production code but conceptually same):
#RequestMapping(value = "/person", method = RequestMethod.PUT)
public Object putPerson(
#RequestParam(value = "name") String name,
HttpServletRequest req) {
long id = createPerson(name);
String uriStart = RestUtils.getSchemeHostPortUrlPart(req
.getRequestURL().toString());
String uri = uriStart + "/person/" + id;
Person person = new Person(name, id, uri);
return person; //Serialized to json by Spring & Jackson
}
//Simple bean-like class
public class Person {
//Getter methods for uri, name & id
}
Since this is quite a boiler plate code which repeats in every method I was wondering if Spring does not have support for this which eluded me when reading it's documentation.
By this I mean accessing either URL without neededn HttpServletRequest or even better its schema, host, port part only.
The documentation provides a lot of examples for constructing URIs using a UriComponentsBuilder.
Furthermore I recommend to take a look at Spring HATEOAS if you want to take your REST API to the next level.
BTW: PUT means that you place what you send (request body) to the location to which you send it (URL). If nothing is there something new is created, otherwise what exists is updated (replaced).
This is not what is happening in your example. The proper way would be to either POST to /person or PUT to the person's own URL, e.g. /person/1234, provided you have the ID beforehand.
You can construct the URI in an interceptor (that's executed previous to controller methods) and put it as an attribute and use it in the controller method.
I believe it is quite simple. Look at this example:
#RequestMapping(value = "/person", method = RequestMethod.PUT)
public Object putPerson(#RequestParam(value = "name") String name, HttpServletRequest req) {
long id = createPerson(name);
Person person = new Person(id, name, req);
return person; //Serialized to json by Spring & Jackson
}
public class JsonResponse {
private String url;
public JsonResponse(HttpServletRequest request) {
url = request.getRequestURI() + "?" + request.getQueryString();
}
public final String url() {
return url;
}
}
public class User extends JsonResponse {
private Long id;
private String name;
public User(Long id, String name, HttpServletRequest request) {
super(request);
this.id = id;
this.name = name;
}
// Getter, Setter
}
You can use org.springframework.web.servlet.support.ServletUriComponentsBuilder like this:
String uri = ServletUriComponentsBuilder.fromCurrentRequest()
.replacePath("/person/{id}")
.buildAndExpand(id)
.toUriString();

spring mvc - The request sent by the client was syntactically incorrect

I checked the threads concerning this and none is helping me. I am new to spring and I get this error when I try to send request values by parameter.
#RequestMapping(value="/receipt", params = "id", method=RequestMethod.GET)
public String index(#PathVariable String id, ModelMap model){
return "receipt"
}
Now when I try to access the url using the url: localhost:8080/url/receipt?id=10, i get that error.
You declare id as PathVariable, but you pass it as a RequestParamter.
If you want to access your function with url: localhost:8080/url/receipt?id=10, you should change you function to:
#RequestMapping(value="/receipt", method=RequestMethod.GET)
public String index(#RequestParam(value = "id", required = true) String id){
return "receipt";
}

Categories

Resources