Sending id or age as requestparam in spring boot producing different results - spring

I have recently started learning spring boot and when I am trying to pass id or age in postman to test it I am getting value as 1 for id and 25 for age (I have declared id and age as Integers in method parameter).
Here is a code from controller
#RestController
#RequestMapping("/student/")
public class StudentController {
#GetMapping()
public Integer getStudents( #RequestParam() Integer id,#RequestParam() Integer age ){
return age;
}
Here is the screenshot from postman
When I declare id and age as Strings in method params The results are 1,value for id and 25,value for age .
For all the other queryparams the reults are as expected .
What is the reason for this? How does spring convert types?
Any help is appreciated . Thank you .

As per this community issue https://github.com/spring-projects/spring-framework/issues/10584
I see a comment stating
Annotation properties can only be of type String, Enumeration, Class, Annotation, primitives, or arrays of these types.
Can you please try with int ?
Check this article too, if this is relating to your issue
How to give default value as integer in #RequestParam()

Related

How does field mapping happen for a PUT request body?

I am stuck with a basic confusion which I cannot test and cannot find a straightforward answer to as well.
I have an endpoint PUT which expects an object in the body , RequestObject.
It consists of 1 field only.
class RequestObject {
String name;
}
Now from the service from which I am hitting this endpoint, the object that I am supposed to use to send in the request has 2 fields.
class Test {
String firstname;
String age;
}
If I make a request, with age as null,
Will this work ?
Since firstName and name are not the same "spellings", will the mapping happen automatically ?
I am assuming No for both but I am not sure how to confirm.
WIll appreciate if someone can point me in right direction.
Thanks
#JsonIgnoreProperties(ignoreUnknown = true)
class RequestObject {
#JsonProperty("firstname")
String name;
}
By default Spring Boot uses the Jackson library to convert to objects. You can customize it using annotations. See https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

Spring Data JPA returning wrong results

I am testing Spring-Data-JPA with Spring-Boot, using hibernate-core 5.4.2.Final version.
For example, I have a Users table containing address and other columns.
My repository interface for this table is as below.
public interface UsersRepository extends JpaRepository<Users, Integer> {
List<Users> findByAddressContaining(String keyword)
}
To my knowledge, if I name the method like I did, the query below will be executed.
SELECT * FROM Users u WHERE address LIKE '%keyword%';
The problem is, this partly works.
For example, there are two datas in users table, each datas having address of "abc" and "cde".
If i test the findByAddressContaing("abc"), the result size of List<> is 2.
Right after if I run findByAddressContaining("de"), the result should be 1, but it is 2.
If i run the same method findByAddressContaining("de") again, then the result becomes 1.
I can't find the way to solve this problem. Any suggestions would be helpful. :)
THE PROBLEM WAS NOT WITH THE Spring-Data-JPA, it was with Request Parameter.
This is my controller method.
#GetMapping("/v2/warehouses")
public void getAllWarehouses(#RequestParam(name = "address") String address,
#RequestParam(name = "limit") Integer limit,
#RequestParam(name = "offset") Integer offset,
HttpServletResponse response) {
System.err.println("Request Param Address : " + address");
If I send request to the correct path using Postman, sometimes address comes as blank.("")
Does this happen normally??
So the basic problem was not with the #RequestParam annotation, it was with the application.properties file.
After I added server.tomcat.uri-encoding=UTF-8 to the properties file, the bug didn't happen anymore.
Thanks!

JAX-RS PUT method. How does the input media declared by the #Consumes annotation get injected in the method's parameter?

I have the following method declared in my resource class.
#Path("{id:\\d+}")
#PUT
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response putPerson(#PathParam("id") long id, Person person) {
logger.debug("Going to update the person with id: {} to name {} age {} and salary {}", id, person.getName(), person.getAge(), person.getSalary());
db.put(id, person);
return Response.noContent().build();
}
Here I understand that my {id} path value does get injected in the id parameter due to the #PathParam annotation. But I am curious how does the input media declared by the #Consumes annotation get injected in the person parameter? I am wondering because there are no annotation declared to inject any value into the person parameter.
I know that the media does get injected because my logger statement does print the correct values.
Is this inject process documented somewhere in the Jersey user manual or any JavaDocs?
I did find the answer in the Jersey User Guide for version 2.31 release in section 7.1. It reads the following.
Unlike method parameters that are associated with the extraction of
request parameters, the method parameter associated with the
representation being consumed does not require annotating. In other
words the representation (entity) parameter does not require a
specific 'entity' annotation. A method parameter without an annotation
is an entity. A maximum of one such unannotated method parameter may
exist since there may only be a maximum of one such representation
sent in a request.

Postman return null values in response

I have created a simple Java spring boot API to add employees. I want to check to employee add endpoint. When I try with it in postman I am getting null values in response.
But its status is 200 and id auto-increment is also working fine.
Controller:
#RestController
#RequestMapping("/api/vi")
public class EmplyeeController {
#PostMapping("/add")
public Employee addEmployee(#RequestBody Employee employee) {
return employeeRepository.save(employee);
}
}
Repository:
#Repository
public interface EmployeeRepository extends JpaRepository<Employee,
Long>{}
How can I solve this? This is my first spring boot application. I wish your help to solve this. Thank you.
You need to correct your payload as Spring bind your payload with Entity when it should have the same attribute but In your case you are using _ "underscore" in your payload and in Entity you are using camelCase so the solution would be updating the post payload and then it will work.
{
"emailAddress":"",
"firstName":"",
"lastName":""
}
Hello i was also facing the same issue, check in application.properties where spring.datasource.url=jdbc:mysql://127.0.0.1:3306/product, weather its mapped to exact schema name in mysql db, i.e case sensitive, previously i have given as /Product
I was having the same problem solved by adding #RequestBody
public ResponseEntity<Employee> addEmployee(#RequestBody Employee employee){
Employee employee1 = employeeService.addEmployee(employee);
return new ResponseEntity<>(employee1,HttpStatus.CREATED);
}
Basically we want to provide the fields as same as entity and check once if there is spaces in the postman like
Ex: " empname":"sudha" (wrong) -> if u will give like this in that time also will get nulls
"empname":"sudha" (right)

POST / GET Request Param Validation in Spring Boot

I am using spring boot. I want to validated the POST request params. So I have gine through #Validated annotation but this require creating a different class for Every API. How should I write my code?
As for example, this is my api
#RequestMapping("/tags/{tagId}/{tagParentId}")
public Response<Demo> a(#PathVariable int tagId, #PathVariable int tagParentId){
... code
}
#RequestMapping("/data/{courseId}/{instId}")
public Response<Demo> b(#PathVariable int courseId, #PathVariable int instId){
... code
}
How should I change my code to add params validation for there API's such that I do not need to create two different validation class? Just one class and then I can add different functions for different API's.
#Validated should be used, to check that a parameter is syntactical correct.
As you are using int values, this is already done by spring.
If tagId is not a valid int, the client will already receive a Http error code.
The validation, whether there is a tag with the given tagId is implicitly done in your code, you do not need an additional validator for that.
If you read tags for example from the database, and you cannot find a tag for the tagId, you should
return new ResponseEntity(HttpStatus.NOT_FOUND);
from your controller method.
You may need to change the return type of your controller method to a common superclass or just to Object, to allow returning the ResponseEntity.
Its also possible to throw exceptions in the controller methods and to configure spring to return a regarding HttpStatus.
See exception-handling-for-rest-with-spring

Resources