Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 4 @RequestMapping -- consumes vs headers?

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?

like image 559
Chris Avatar asked Jun 18 '15 18:06

Chris


People also ask

What is the use of consumes in RequestMapping?

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.

What is the use of @RequestMapping annotation in spring?

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 .

What is difference between RequestMapping and GetMapping?

@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.

What is true about @RequestMapping annotation in Spring MVC?

@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.


1 Answers

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.

like image 107
Alex Ander Avatar answered Oct 05 '22 23:10

Alex Ander