Issue
I have a simple REST controller written in a Spring-boot application but I am not sure how to implement the content negotiation to make it return JSON or XML based on the Content-Type parameter in the request header. Could someone explain to me, what am I doing wrong?
Controller method:
@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public Message getMessageXML(@RequestParam("text") String text) throws Exception {
Message message = new Message();
message.setDate(new Date());
message.setName("Test");
message.setAge(99);
message.setMessage(text);
return message;
}
I always get JSON when calling this method (even if I specify the Content-Type
to be application/xml
or text/xml
).
When I implement two methods each with different mapping and different content type, I am able to get XML from the xml one but it does not work if I specify two mediaTypes in a single method (like the provided example).
What I would like is to call the \message
endpoint and receive
- XML when the Content-Type of the GET request is set to application/xml
- JSON when the Content-Type is application/json
Any help is appreciated.
EDIT: I updated my controller to accept all media types
@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE)
public Message getMessageXML(@RequestParam("text") String text) throws Exception {
Message message = new Message();
message.setDate(new Date());
message.setName("Vladimir");
message.setAge(35);
message.setMessage(text);
return message;
}
Solution
You can find some hints in the blog post @RequestMapping with Produces and Consumes at point 6.
Pay attention to the section about Content-Type and Accept headers:
@RequestMapping with Produces and Consumes: We can use header Content-Type and Accept to find out request contents and what is the mime message it wants in response. For clarity, @RequestMapping provides produces and consumes variables where we can specify the request content-type for which method will be invoked and the response content type. For example:
@RequestMapping(value="/method6", produces={"application/json","application/xml"}, consumes="text/html") @ResponseBody public String method6(){ return "method6"; }
Above method can consume message only with Content-Type as text/html and is able to produce messages of type application/json and application/xml.
You can also try this different approach (using ResponseEntity object) that allows you to find out the incoming message type and produce the corresponding message (also exploiting the @ResponseBody annotation)
Answered By - abarisone
Answer Checked By - Marilyn (JavaFixing Volunteer)