XML/JSON POST with RequestBody in Spring REST Controller - json

I am creating a RESTful website with Spring 3.0. I am using ContentNegotiatingViewResolver as well as HTTP Message Convertors (like MappingJacksonHttpMessageConverter for JSON, MarshallingHttpMessageConverter for XML, etc.). I am able to get the XML content successfully, if I use the .xml suffix in the last of url and same in case of JSON with .json suffix in URL.
Getting XML/JSON contents from controller doesn't produce any problem for me. But, how can I POST the XML/JSON with request body in same Controller method?
For e.g.
#RequestMapping(method=RequestMethod.POST, value="/addEmployee")
public ModelAndView addEmployee(#RequestBody Employee e) {
employeeDao.add(e);
return new ModelAndView(XML_VIEW_NAME, "object", e);
}

You should consider not using a View for returning JSON (or XML), but use the #ResponseBody annotation. If the employee is what should be returned, Spring and the MappingJacksonHttpMessageConverter will automatic translate your Employee Object to JSON if you use a method definition and implementation like this (note, not tested):
#RequestMapping(method=RequestMethod.POST, value="/addEmployee")
#ResponseBody
public Employee addEmployee(#RequestBody Employee e) {
Employee created = employeeDao.add(e);
return created;
}

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 {
(...)
}

Spring Boot ExceptionHandler is returning XML and not JSON

My whole API generates JSON without any problem, but as soon as an exception is thrown, the controller decides to stringy the object to XML... why?
My controller looks like this:
#RestController
public class Controller{
#ResponseBody
#ExceptionHandler({ IllegalArgumentException.class, MissingServletRequestParameterException.class})
#ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, Object> invalid(Exception ex){
return new ObjectResponseBuilder().add("message", ex.getMessage()).get();
}
}
However this is the response I get:
<Map>
<message>Required request parameter 'min' for method parameter type Long is not present</message>
</Map>
I'm making the request directly from the browser, so no header is set... just like for all the others endpoints (that are returning JSON instead)

How to customize Jackson JSON serialization based on request parameter in Spring MVC

I am working on a project and we want to pass down custom ContextAttributes to the Jackson ObjectMapper#writer() method.
Basically I am imagining some kind of global piece of code that sits between the controllers and serialization. It should look at the HttpServletRequest, get a parameter and then hook into the serialization.
Writing a custom HttpMessageConverter doesn't seem to be enough because it does not have access to the request.
You can access Request this way
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
if (ra instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes)ra).getRequest();
}
Or you can add a Filter and store Request in a ThreadLocal storage and acccess from your custom HttpMessageConverter.
You can create a filter and apply that for all urls and implement the logic in the filter. The filter has access to request object
public class FilterName extends GenericFilterBean {
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) {
//TODP
}
}
and add this to the security xml

How to create angularjs springboot application that stores data to a mysql database. using json

I'm kinda stuck on this topic.
This is what i already found out.
A good tutorial was :
Using MySQL in Spring Boot via Spring Data JPA and Hibernate
http://blog.netgloo.com/2014/10/27/using-mysql-in-spring-boot-via-spring-data-jpa-and-hibernate/
I also found some information how to make single page application with hsqldb.
But i really want to create something that permanent saves the users data to the database using mysql.
But in order to use angular http i need json. Can i convert the urls like
/create?email=[email]&name=[name]
To json how should i proceed. Does anyone knows good tutorials on this. Or are there better way's to proceed.
The simplest/handy way to consuming JSON with Spring Boot is using a Java class that resembles your JSON (https://stackoverflow.com/a/6019761).
So, you can follow the tutorial you linked, then use a controller like this one to handle JSONs:
#RestController
public class UserController {
#RequestMapping(
value = "/user/create",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> createUser(#RequestBody User user) {
try {
// Handle the User object here
userDao.save(user);
}
catch (Exception ex) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(HttpStatus.OK);
}
// ...
}
Receiving a JSON like this (at the url /user/create):
{email: "john#doe.com", name: "John Doe"}
An user will be saved in your database.
Responding with JSON
Moreover, if you want to send a response as JSON from your controller you should create a java object then send it back as response, within the ResponseEntity object.
For example, suppose to have this class:
public class SuccessDto {
private String success;
public SuccessDto(String success) {
this.success = success;
}
}
You can change your controller in this way:
public ResponseEntity<SuccessDto> createUser(#RequestBody User user) {
// ...
return new ResponseEntity<>(
new SuccessDto("true"),
HttpStatus.OK
);
}
and you will have this JSON as response
{success: "true"}
if you have already managed to use it with HSQLDB, it's juste a matter of database properties (like the JDBC URL) and schema initialization.
Can you provide the code sample of the controller, how you save the data (via a Repository or a simple DAO ?) and the application.properties

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