29

If a request is sent to my API without an Accept header, I want to make JSON the default format. I have two methods in my controller, one for XML and one for JSON:

@RequestMapping(method = RequestMethod.GET,produces=MediaType.APPLICATION_ATOM_XML_VALUE)
@ResponseBody
public ResponseEntity<SearchResultResource> getXmlData(final HttpServletRequest request) {
     //get data, set XML content type in header.
 }

 @RequestMapping(method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
 @ResponseBody
 public ResponseEntity<Feed> getJsonData(final HttpServletRequest request){
      //get data, set JSON content type in header.  
 }

When I send a request without an Accept header the getXmlData method is called, which is not what I want. Is there a way to tell Spring MVC to call the getJsonData method if no Accept header has been provided?

EDIT:

There is a defaultContentType field in the ContentNegotiationManagerFactoryBean that does the trick.

RustyTheBoyRobot
  • 5,891
  • 4
  • 36
  • 55
user86834
  • 5,357
  • 10
  • 34
  • 47

2 Answers2

37

From the Spring documentation, you can do this with Java config like this:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  @Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.defaultContentType(MediaType.APPLICATION_JSON);
  }
}

If you are using Spring 5.0 or later, implement WebMvcConfigurer instead of extending WebMvcConfigurerAdapter. WebMvcConfigurerAdapter has been deprecated since WebMvcConfigurer has default methods (made possible by Java 8) and can be implemented directly without the need for an adapter.

RustyTheBoyRobot
  • 5,891
  • 4
  • 36
  • 55
  • 2
    Just a detail: in a Spring boot application, your `@Configuration` class should **not** contain the `@EnableWebMvc` annotation ([source](https://dzone.com/articles/spring-boot-enablewebmvc-and-common-use-cases)). It may prevent other things from working, such as the springfox-swagger-ui html page. – Paulo Merson May 30 '18 at 17:37
  • 4
    `WebMvcConigurerAdapter` is deprecated now, just have to change `extends WebMvcConfigurerAdapter` to `implements WebMvcConfigurer` – Taylor O'Connor Nov 30 '18 at 15:40
  • Downvoted for misuse of @EnableWebMvc. Spring Boot shouldn't mix with it. – emeraldhieu Jul 25 '20 at 05:49
13

If you use spring 3.2.x, just add this to spring-mvc.xml

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false"/>
    <property name="mediaTypes">
        <value>
            json=application/json
            xml=application/xml
        </value>
    </property>
    <property name="defaultContentType" value="application/json"/>
</bean>
Larry.Z
  • 3,694
  • 1
  • 20
  • 17
  • I put this in my servlet-context.xml and it worked perfectly. Thanks @Larry Z. – UpAllNight Aug 13 '13 at 17:47
  • Does setting `mediaTypes` has any effect when `favorPathExtension` is set to `false`? – holmis83 Feb 24 '14 at 11:59
  • 2
    mediaTypes is used when favorParameter is set to true. This will check for query params, so /blahblah/4?format=xml would resolve to application/xml. The default value for favorParameter is false, so in this example setting mediaTypes has no effect. – Dick Chesterwood Oct 30 '14 at 19:04
  • 2
    Hi, after including the above code i am getting json as default if no accept headers. but if i set as application/xml . still im getting the response as json instead of XML?what im missing ? – Sundar G Nov 22 '17 at 14:07