I have a question in regards to the consumes and produces part of the @RequestMapping
. I have an endpoint that I want to accept both JSON and XML and return JSON when JSON is passed in and return XML when XML is passed in. Is there anything special that I have to do to make this work?
Sample code is listed below.
@RequestMapping(value = "/something", method = PUT,
consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE},
produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
public SomeObject updateSomeObject(SomeObject acct) {
return doStuff(acct);
}
Will this work the way I'm expecting or do I need two endpoints updateSomeObjectXML
and updateSomeObjectJson
to handle both cases?
Thanks, Mike
The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. If @Consumes is applied at the class level, all the response methods accept the specified MIME types by default.
One of the most important annotations in spring is the @RequestMapping Annotation which is used to map HTTP requests to handler methods of MVC and REST controllers. In Spring MVC applications, the DispatcherServlet (Front Controller) is responsible for routing incoming HTTP requests to handler methods of controllers.
The @RequestMapping annotation can be applied to class-level and/or method-level in a controller. The class-level annotation maps a specific request path or pattern onto a controller. You can then apply additional method-level annotations to make mappings more specific to handler methods.
value method is an alias for path method. This is an alias for path(). For example @RequestMapping("/foo") is equivalent to @RequestMapping(path="/foo"). So both methods are similar in that sense.
The article from the Spring blog - Content Negotiation using Spring MVC - provides details on how content negotiation works with Spring MVC, in brief if you want the same endpoint to handle XML and JSON, your mapping is correct, to summarize from the article:
Use path extension - you can send a json to /something.json
and xml to /something.xml
and expect the same thing on the way back
Use the Accept
header, use a value of application/json
or application/xml
and use Content-Type
to specify the submitted media type.
Short answer:
Annotate the method with @ResponseBody, and the method parameter with @RequestBody, and it will work (no need for 2 methods).
Explanation:
First, produces and consumes attributes are used to narrow the mapping types. By default the first HttpMessageConverter found, that matches the media type requested, will be used.
Second, client requests a media type by giving the media type in:
- Accept request header
- URL sufix (http: //....//some .xml => "application/xml" media type requested)
- URL format parameter (.../some?format=xls)
Third, produces in combination with @ResponseBody will produce the object in the requested media type (nice for GET requests, when you need to send something back to the client), and consumes in combination with @RequestBody will consume the object with the requested media type (nice for POST requests, when you need to get something from the client).
Four, when @ResponseBody not used, HttpMessageConverters are not used. Rather ViewResolvers kick in and produce a view (HTML, PDF...), and the return type should follow the rules that accompany ViewResolvers (check default view resolver and InternalResourceViewResolver for more).
Hope it helps.
Other sources:
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#consumes--
http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc
Well,
consumes/produces takes String[]
as a parameter (see RequestMapping from Spring's documentation) so I believe it will work. You can also try headers = "content-type=application/json,application/xml"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With