Spring boot controller content negotiation
You can use ContentNegotiationConfigurer
Firstly, you should override the configureContentNegotiation
method in your configuration class:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML);
}
}
favorParameter(true)
- enabling favoring path expressions over parameter or accept headers.
defaultContentType(MediaType.APPLICATION_JSON)
- sets the default content type. this means that if you don't pass a path expression then Spring will generate JSON as response.
mediaType("xml", MediaType.APPLICATION_XML)
- sets the path expression key for XML.
Now if you declare your Controller like:
@Controller
class AccountController {
@RequestMapping(value="/accounts", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody List<Account> list(Model model, Principal principal) {
return accountManager.getAccounts(principal) );
}
}
and call it something like localhost:8080/app/accounts.json
, then Spring will generate JSON as response. So if you call localhost:8080/app/accounts.xml
you will receive XML response
You can find more info about this here.
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)