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 = \"Acce
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.
As the javadoc of HeadersRequestCondition (which handles the value provided in the headers
attribute of a @RequestMapping
annotation) states
Expressions passed to the constructor with header names 'Accept' or 'Content-Type' are ignored. See ConsumesRequestCondition and ProducesRequestCondition for those.
So don't use those headers in headers
. Use the produces
and consumes
attributes for Accept
and Content-Type
.
As to how to use them, the documentation gives examples: for consumes and for produces.