How to accept json data though post in spring boot rest - json

PostMapping method
#RestController
#RequestMapping("/validate")
public class Validatesimapi {
#PostMapping
public Simoffers validateSim(#RequestBody ???)
}
I want to pass following json object through post request and accept it in validateSim. What should I write at ???.
{
"id": "1234",
"num":"2343335"
}
both the datatypes of id and num is String.
enter code here

It’s as simple as adding a DTO with the fields that you want. The Jackson mapper will map the json to that object.

Related

Validation of JSON Object With #Valid and #Requestbody in SpringBoot

I am trying to validate a JSON body within a post method. Here is a sample code:
#PostMapping(value = "GetInfo")
public ResponseEntity<Person> getOffers(#Valid #RequestBody InfoRequest infoRequest) {
//generate person response according to inforequest JSON.
Person person = PersonGenerator.getOffers(infoRequest);
return new ResponseEntity<>(person, HttpStatus.OK);
}
When I send JSON body to get info (for ex: Name and Age) I want the program to throw an error if some extra fields are entered that are not needed for the Person class. As an example in below ExtraField. But #RequestBody and #Valid annotations are just checking for fields that have a match. Since it is filtered (afaik in this case ExtraField is filtered) I can't get full JSON to analyze infoRequest to find if any extra information was sent.
{
"Name": "sample",
"Age": "sample",
"ExtraField": "prevent",
}
I know there are some libraries to check JSON files. But first I have to know what is coming :).
If there is no annotation to see extra fields entered. How can I extract and analyze JSON file*
Note: Changing parameter type infoRequest as String is not an option for security purposes.
By default, the Spring Boot configuration will disables Jackson DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES feature. One possible solution could be enabling it again in you application.yml file as follows:
spring.jackson.deserialization.fail-on-unknown-properties=true
This will change the behaviour for Jackson ObjectMapper if you want finer-grained configuration you might use #JsonIgnoreProperties(ignoreUnknown = false) as follows:
#JsonIgnoreProperties(ignoreUnknown = false)
public class InfoRequest {
(...)
}

Validate json values in response body before sending to spring controller to avoid response code 400

My Spring controller accepts application json response body as an object parameter. I don't see where I can intercept the json to validate the values before Spring controller receives it and complains when it doesn't cast.
Example: User sends json to endpoint - /createUser
Expecting: {"username":"johndoe", "pin": 1234}
Receives: {"username": 1234, "pin": "johndoe"}
If string is sent for int or vice versa, server will show status 400. I'd like to validate the data myself and provide a custom json that details the values that are incorrectly set.
Thanks in advance!
You could create your own class for the #RequestBody param in your controller and make a validation on them. You could use some supported annotations or create on your own. But don't forget to put the #Valid next to the #RequestBody, that's the key. E.g
#RestController
public class UserController {
#PostMapping("/users")
ResponseEntity<String> addUser(#Valid #RequestBody User user) {
// persisting the user
return ResponseEntity.ok("User is valid");
}
// standard constructors / other methods
}
For more information, you could find them here validation, create your own validator.

How to parse json arrary?

I have come across a problem of parsing json data . I am building project using spring boot based on REST api . When i have to parse data corresponding to domain then it is very easy , i use RequestBody in controller method with domain name but in current scenerio i have a list of domain in json form :
{
"data":[
{
"type":"abc",
"subtypes":[
{
"leftValue":"BEACH",
"rightValue":"MOUNTAIN",
"preferencePoint":60
},
{
"leftValue":"ADVENTURE",
"rightValue":"LEISURE",
"preferencePoint":60
}
]
},
{
"type":"mno",
"subtypes":[
{
"leftValue":"LUXURY",
"rightValue":"FUNCTIONAL",
"preferencePoint":60
},
{
"leftValue":"SENSIBLE",
"rightValue":"AGGRESIVE",
"preferencePoint":0
}
]
}
]
}
I am sending data in list where type is the property of class Type
and class Type has list of Subtypes class and subtype class contains leftValue and rightValue as enums
I am using spring boot which uses jackson liberary by default and i want to parse this data into corresponding Type class using Jackson. Can any one provide me solution.
It wasn't clear to me if you have static or dynamic payload.
Static payload
For static one, I would personally try to simplify your payload structure. But your structure would look like this. (I skipped getters and setters. You can generate them via Lombok library).
public class Subtype{
private String leftValue;
private String rightValue;
private int preferencePoint;
}
public class Type{
private String type;
private List<Subtype> subtypes;
}
public class Data{
private List<Type> data;
}
Then in your controller you inject Data type as #RequestBody.
Dynamic payload
For dynamic payload, there is option to inject LinkedHashMap<String, Object> as #RequestBody. Where value in that map is of type Object, which can be casted into another LinkedHashMap<String, Object> and therefore this approach support also nested objects. This can support infinite nesting this way. The only downside is that you need to cast Objects into correct types based on key from the map.
BTW, with pure Spring or Spring Boot I was always able to avoid explicit call against Jackson API, therefore I don't recommend to go down that path.

Spring MVC : post request and json object with array : bad request

I'm trying to retrieve parameters from a http POST request with Spring MVC.
The request contains the following json object (content-type : application/json), which itself contains an array of customObjects :
{
"globalId":"338",
"lines":[
{
"id": "someId",
"lib":"blabla",
...
}
]
}
Here's the code I'm trying to use :
#RequestMapping(method = RequestMethod.POST, value = "/valider")
#ResponseBody
public void valider(final HttpServletRequest request, #RequestParam("globalId") final String globalId, #RequestParam("lines") final MyCustomObject[] lines) {
All I'm getting is a "bad request" error (http 400).
Is it possible to separately retrieve the two parameters "globalId" and "lines" ? Or since they are in the same json object, it has to be treated has a single parameter ? How do you proceed when you have more than one parameter in a Post request ?
I think you're looking for something like `#RequestBody. Create a class to represent your JSON data. In your case, this class will contain two member variables - globalId as a string and lines as an array of the object it represents. Then in your controller method, you will use the #RequestBody annotation on this class type so that Spring will be able to convert the JSON into object. Check the examples below.
http://www.leveluplunch.com/java/tutorials/014-post-json-to-spring-rest-webservice/
JQuery, Spring MVC #RequestBody and JSON - making it work together
http://www.techzoo.org/spring-framework/spring-mvc-requestbody-json-example.html
create model object to map your Json data
class DLibrary{
int id;
String lib;
//getters/setters
}
class GLibrary{
int globalId;
List<DLibrary> lines;
//getters/setters
}
Replace your controller code with below
#RequestMapping(method = RequestMethod.POST, value = "/valider")
#ResponseBody
public void valider(#RequestBody GLibrary gLibrary) {
#RequestBody annotation will map Json to Java Object implicitly.
To achieve this spring must require jackson-core and jackson-mapper library included in your application and your Java class should have getter and setters i.e it must follow bean standards.
Indeed, I have to use #RequestBody to get the JSON object.
Quick summary, depending on how the parameters are passed in the http POST body request :
one JSON object (Content-Type: application/json), use #RequestBody to map the json object to a java object
multiple parameters (Content-Type: application/x-www-form-urlencoded), use #RequestParam for each parameter

Is it possible to get jersey to read json variables our of a request body without using a bean?

In jersey a Java bean can be auto-deserialized from within a request body but what if I want to read a parameter without creating a special type. Is it possible to do this using annotations.
My current code is:
public class RequestData {
String param;
}
...
public Response readData(RequestData data) {
data.getParam();
...
}
I want it to be something like:
public Response readData(#RequestParam("param") String param) {
...
}
If its not already clear the input JSON is:
{
"param":"some value"
}
The type of your input JSON is Map<String, String> so if you want to have undifferentiated input you could use that as your request parameter and read the values that you require.
Note that #RequestParam looks at the request parameters and not the body, so it's a different beast.
You do this by letting Jersey pass you String as is (as per annotations), and then data-bind it using Jackson ObjectMapper (thing Jersey uses internally for JSON binding):
Map<String,Object> map = objectMapper.readValue(param, Map.class);
to get access to ObjectMapper, you can use JAX-RS injection annotation (#Context I think?) in the resource class:
#Context
private ObjectMapper objectMapper;