Spring 4 @RequestMapping — consumes vs headers?

前端 未结 2 2075
星月不相逢
星月不相逢 2021-02-03 10:31

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

相关标签:
2条回答
  • 2021-02-03 11:09

    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.

    0 讨论(0)
  • 2021-02-03 11:11

    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.

    0 讨论(0)
提交回复
热议问题