getting null parameter values when I send body from rest client - spring

Iam getting null parameter values when i send values from rest client. But when I send Values from form(html view page) it is working fine.
Below one is my bean class.
public class Home {
private String id;
And I am sending values from rest client as post method.
{
"id":"10",
"load":"true"
}
Content-Type: application/json
Request is coming to the controller class. but it will return all values as null .But when I am sending values from html page it is working fine. Any one can help how to get values.
When I am using #RequestBody in controller calss, I am getting Caused by: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported exception

The annotation #RequestBody should be added on Home homeRequest.
This allows the controller to analyze the request's body as the object's instance itself. This is the case of a JSON request.
Otherwise it is possible to use #RestController instead of #Controller as an annotation of the controller which does the same as #Controller, but it adds implicitly to all the request mapping methods the annotation #RequestBody to the inputs and #ResponseBody to all the response objects.

Related

Mask SSN in spring data rest response body

I am creating a rest service using Spring REST. In few services like Identification, I need to Mask SSN in response. (without usingJSON ignore or JsonProperty)
If clients send the SSN in the request body, the response body for SSN should be masked as shown below. (example, Postman requests body and response)
SSN should be masked as xxx-xxxx-1235 in the response body.
Is there any way in spring data rest to achieve this? Or any common solution that could be applied on all entities/controller when ResponseEntity is returned (like Interceptor)?
I believe the jackson #JsonGetter could be used for this case.
#JsonGetter("ssn")
public String getCensoredSsn() {
return Something.CensorSsn(ssn);
}
I was able to do this two ways. First was to override the get method for the required field and mask it right there. Other way was through combined use of creating CustomSerializer and using #JsonSerialize(using=CustomSerialzier) annotations at a class level.
public class CustomSerializer extends StdSerializer

How the request body of form is passed to spring mvc controller and how to map to pojo class instance?

How the request body of form is passed to the spring MVC controller and how to map to the POJO class instance?
I presume, you are building end point using POST. If yes, you can annotate method parameter with #RequestBody to a capture request body.
Basically, #RequestBody is used to bind the HTTP request body with a domain object in method parameter. Behind the scenes, these annotation uses HTTP Message converters to convert the body of HTTP request to domain objects.
#RequestMapping(value="/user/create", method=RequestMethod.POST)
public void createUser(#RequestBody User user){
// your logic goes here..
// Make sure that parameters in User POJO matches with HTTP Request Parameters.
}
I assume you are using POST API request for your use case. In the spring mvc controller class, we can make use of #RequestBody annotation followed by Pojo class.
Example:
#PostMapping
public ResponseEntity<ResponseDto> saveData(#RequestBody Data data) {
// Access to service layer
}
Let's say you're doing a POST request.
#PostMapping
public void saveSomeData(#RequestBody PojoClass pojoClass){
// whatever you wanna do
}
The #RequestBody annotation extracts the data your client application is sending on the body of the request. Also, you'd want to name the member variables on your pojo class similar to how you named it in on your request body.
Your POJO class can be something like:
public class PojoClass{
private String name;
private int age;
}
Now you can create getters and setters or use the Lombok annotation #Data on the class level to auto-generate the getters and setters.
Hope this was helpful:)

Get raw json string in Spring MVC Rest

Im have #RestController and this method. how can I get any json and then select the handler depending on the method and pass it there for processing
PS. I use GSON instead of JACKSON
You can use #RequestBody in your method and take a String parameter:
public AbstractJsonResponse(#PaqthVariable String method, #RequestBody String json) {
...
}
See here: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestBody.html
Mainly the part that says:
Annotation indicating a method parameter should be bound to the body of the web request

Null check for Request body object

Is it possible to do integration test for null check.
I passed null value.
HttpEntity<Employee> entity = new HttpEntity<Employee>(null, headers);
restTemplate.exchange(url, httpMethod, entity, String.class);
I got the below error.
{"timestamp":"2018-10-06T14:33:52.113+0000","status":400,"error":"Bad Request","message":"Required request body is missing:"}
#RestController
public class EmployeeController {
#PostMapping(value = "/employee/save", produces = "application/json")
public Employee save(#RequestBody Employee employee){
if(employee==null){
throw new RuntimeException("Employee is null");
}
}
}
class Employee {
}
#RequestBody(required=false) Employee employee
please try with required option in #RequestBody.
The problem here is the mapping in spring mvc.
required
Default is true, leading to an exception thrown in case there is no body content. Switch this to false if you prefer null to be passed when the body content is null.
#RequestBody Employee employee
Your method only is processed the request if employee is not null. Then it considered mapping correctly and pass request to this method and handle it. So the check null condition will be needless here.
I am not sure whether it's doable, but I will say it is a bad practice.
According to RFC 7231:
The POST method is used to request that the origin server accept the
representation enclosed in the request as data to be processed by the
target resource.
Since you have annotated your controller PostMapping, there should be request body to server. I don't see the value of writing integration test for null or empty request body.
If we look into the HTTP request structure,
POST /your_url HTTP/1.1
HOST your_host
ContentType ...
ContentLength ...
Body line 1
What's the difference between null and empty?
You can use javax validation framework to check whether #requestbody is null or not
please use below approach: It'll definitely resolve your concern.
Maven Dependency:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
#RestController
public class EmployeeController {
#PostMapping(value = "/employee/save", produces = "application/json")
public Employee save(#NotNull #RequestBody Employee employee){
}
}
You are getting this error message because #RequestBody annotation has default value and you have to send valid request to your method.
You don't need to null check inside of method for request object because #RequestBody has required field and this field's default value is true. If you check the inside of #RequestBody interface you are going to see what I am saying. Also you can see the below;
If you set #RequestBody(required = false) in method's parameter you are not going to get error message, but you need to check your request object is null or not... If you don't check-out of object is null when you use that object you will get "Null Pointer Excepiton"...
your choise...
good luck
You can use #NonNull either with the #RequestBody annotation. Or, even better if you want the variables of the Object to always be non-null after the constructor is called, you can use this annotation in the class itself when defining the variables/attributes.

#ModelAttribute vs #RequestBody, #ResponseBody

#ModelAttribute
RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method =
RequestMethod.POST)
public String processSubmit(#ModelAttribute Pet pet) { }
http://.../?name=Something&age=100
public String doSomething(#ModelAttribute User user) { }
#RequestBody
#RequestMapping(value = "/user/savecontact", method = RequestMethod.POST
public String saveContact(#RequestBody Contact contact){ }
{ "name": "Something", "age": "100" } in request body
public String doSomething(#RequestBodyUser user) { }
#ModelAttribute will take a query string. so, all the data are being pass to the server through the url
#RequestBody, all the data will be pass to the server through a full JSON body
Now which one is the best approach ???
If both are for same purpose to bind to the bean..which one is the best practice or widely used as standard practice?
Both handles multi-part file and does it both have equivalent options with one another ?
https://javabeat.net/spring-multipart-file-upload/
How do i upload/stream large images using Spring 3.2 spring-mvc in a restful way
Does any one of them has lesser capabilities then the other one? Like length limitations, method limitations. Drawbacks
Which one is more secured in terms of security ?
As the javadoc suggests, it's the usage that sets them apart, i.e., use #ModelAttribute if you want to bind the object back to the web view, if this is not needed, use #RequestBody
#RequestBody
Usecases : Restful controllers (ex: produce and consume json/xml, processing direct document download requests, searching for stuff, ajax requests )
As the name suggests the if a method argument is annotated with #RequestBody annotation Spring converts the HTTP request body to the Java type of the method argument.
Is only allowed on method parameters (#Target(value={ PARAMETER}))
The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request.
works for Post and not Get method.
#ModelAttribute
Usecases : web app controllers (ex: binding request query parameters, populating web views with options and defaults)
Uses data binders & ConversionService
Is allowed on methods and method params(#Target(value={METHOD, PARAMETER}))
Useful when dealing with model attributes for adding and retrieving model attributes to and from the Srping’s Model object
When used on METHODS, those methods are invoked before the controller methods annotated with #RequestMapping are invoked
binds a method PARAMETER or method return value to a named model attribute & the bound named model attributes are exposed to a web view
binds request query parameters to bean
For more information on Data Binding, and Type Conversion refer: https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/core.html#validation

Resources