I'm learning how to build RESTful web services using Spring 4, and one thing I'm not clear on is in @RequestMapping. I've seen examples where one uses headers = "Accept=application/xml"
and other examples using consumes (or produces) = "application/xml"
.
For instance, in my own @RestController class, I have this function...
// POST
@RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml")
public User create(@RequestBody User user) {
LOG.info("User = " + user.toString());
return userService.create(user);
}
What is the difference between using headers = "Accept=application/xml"
vs. using consumes = "application/xml"?
Or even using headers = "content-type=application/xml"
?
Could someone explain the differences between headers and consumes/produces, and when each is used?
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.
RequestMapping annotation is used to map web requests onto specific handler classes and/or handler methods. @RequestMapping can be applied to the controller class as well as methods. Today we will look into various usage of this annotation with example and other annotations @PathVariable and @RequestParam .
@RequestMapping is used at the class level while @GetMapping is used to connect the methods. This is also an important Spring MVC interview question to knowing how and when to use both RequestMapping and GetMapping is crucial for Java developers.
@RequestMapping allows easy mapping of URL parameters with the @RequestParam annotation. We are then extracting the value of the id parameter using the @RequestParam(“id”) annotation in the controller method signature. In this example, the parameter was bound directly without having been declared first.
SHORT ANSWER
In the example you have above, using headers = "Accept=application/xml"
or produces = "application/xml"
will both respond to the client the same way i.e. send a response to the client with XML representation.
LONGER ANSWER
i. Headers
For RESTful web services, the client (e.g. your browser) sends a request (e.g. GET, POST, etc.) to a server, and the server will send a response back. This is an HTTP Transaction. Both the request and response have HTTP header fields ("headers"), which define the operating parameters of an HTTP transaction (I will refer to the headers for client request as "request headers", and these differ from headers from server response "response headers").
As part of the request your browser sends to server, there are different request headers and some examples include Accept
, Connection
, Content-Length
etc. and each of these headers have their own function (see a full list of headers here: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields).
Using your code example, if a client does a POST request, Spring will check the request header(s) and if it finds a header Accept
with a value of application/xml
, it will map the request to the create
method you have above (and in your case the server will return an XML response representation to the client).
Let me modify the headers
element in the code you provided:
@RequestMapping(method = RequestMethod.POST, headers = "Connection=keep-alive")
public User create(@RequestBody User user) {
...
}
Notice the headers
element now has a value of Connection=keep-alive
. If a client does a POST request, Spring will check the request header(s) and if it finds a header Connection
with a value of keep-alive
, it will map that client request to the create
method above.
ii. Produces and Consumes
If you used produces="application/xml"
for the create
method, this means a client request is only mapped to the create
method if the client's Accept
header matches application/xml
. This essentially is the client saying, "Hey server, I prefer to accept your response in XML representation, so send your response to me in XML". Effectively, the produces="application/xml"
is also the server saying, "Hey client, I can only produce responses for you in XML representation, so I will send you that format".
Link to Spring documentation reference.
If you used consumes="application/xml"
for the create
method, this means a client request is only mapped to the create
method if the client's Content-Type
header matches application/xml
(the Content-Type
request header describes the representation the client request is coming in). This essentially is the server saying, "Hey client, I can only consume requests in XML representation, so send that format to me".
SUMMARY
The headers
element within the @RequestMapping
annotation can take different request headers (Accept
, Connection
, Cache-Control
etc.), but the produces
element is only concerned with the Accept
request header and the consumes
element is only concerned with the Content-Type
request header.
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