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