nybon
nybon

Reputation: 9601

Content negotiation in Spring MVC

I am writing a RESTful web application with Spring 3, and part of my application needs to process the data according to the requested media type.

@RequestMapping(...)
public String process() {
  if(requested_media_type_is_xml) {
     processXml();
  }
  else if(requested_media_type_is_json) {
     processJson();
  }
  return something;
}

Aka, my application logic is completely different if client requests different media type, so it seems Spring's ContentNegotiatingViewResolver or message converter are not very useful in this case because I want to route the request to different processing code rather than run the same code snippet and render them with different format according to the requested media type.

As far as I know, in JAX-RS, Jersey for example, you can use @Consume annotation for this. I wonder what is the Spring way to do this? Thanks.

Upvotes: 3

Views: 8805

Answers (2)

nybon
nybon

Reputation: 9601

Although skaffman's answer is correct, I found in the latest Spring release (3.1 M2), there is an alternative and better way to do this, using consumes and produces values:

@RequestMapping(value="/pets", consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
    // ...
}

@Controller
@RequestMapping(value = "/pets/{petId}", produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
    // ...
}

Please check out more details here: http://blog.springsource.com/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2/

Update:

Here are the official Spring documentation about this:

http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-consumes

http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-produces

Upvotes: 10

skaffman
skaffman

Reputation: 403551

The @RequestMapping annotation has an optional headers attribute that allows you to narrow the mapping to requests with specific headers, e.g. to match XML:

@RequestMapping(value = "/something", headers = "content-type=application/xml")

You can also specify multiple variants:

@RequestMapping(value = "/something", headers = [{"content-type=application/xml","content-type=text/xml"}])

It's a little bit low level, but does the job.

Upvotes: 2

Related Questions