Multiple scenarios @RequestMapping produces JSON/XML together with Accept or ResponseEntity Multiple scenarios @RequestMapping produces JSON/XML together with Accept or ResponseEntity spring spring

Multiple scenarios @RequestMapping produces JSON/XML together with Accept or ResponseEntity


Using Accept header is really easy to get the format json or xml from the REST service.

This is my Controller, take a look produces section.

@RequestMapping(value = "properties", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}, method = RequestMethod.GET)    public UIProperty getProperties() {        return uiProperty;    }

In order to consume the REST service we can use the code below where header can be MediaType.APPLICATION_JSON_VALUE or MediaType.APPLICATION_XML_VALUE

HttpHeaders headers = new HttpHeaders();headers.add("Accept", header);HttpEntity entity = new HttpEntity(headers);RestTemplate restTemplate = new RestTemplate();ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/properties", HttpMethod.GET, entity,String.class);return response.getBody();

Edit 01:

In order to work with application/xml, add this dependency

<dependency>    <groupId>com.fasterxml.jackson.dataformat</groupId>    <artifactId>jackson-dataformat-xml</artifactId></dependency>


All your problems are that you are mixing content type negotiation with parameter passing. They are things at different levels. More specific, for your question 2, you constructed the response header with the media type your want to return. The actual content negotiation is based on the accept media type in your request header, not response header. At the point the execution reaches the implementation of the method getPersonFormat, I am not sure whether the content negotiation has been done or not. Depends on the implementation. If not and you want to make the thing work, you can overwrite the request header accept type with what you want to return.

return new ResponseEntity<>(PersonFactory.createPerson(), httpHeaders, HttpStatus.OK);


I've preferred using the params filter for parameter-centric content-type.. I believe that should work in conjunction with the produces attribute.

@GetMapping(value="/person/{id}/",             params="format=json",            produces=MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<Person> getPerson(@PathVariable Integer id){    Person person = personMapRepository.findPerson(id);    return ResponseEntity.ok(person);} @GetMapping(value="/person/{id}/",             params="format=xml",            produces=MediaType.APPLICATION_XML_VALUE)public ResponseEntity<Person> getPersonXML(@PathVariable Integer id){    return GetPerson(id); // delegate}