Close

Spring MVC - Setting Default Content Type with ContentNegotiationConfigurer

[Last Updated: Jul 20, 2017]

In Spring MVC, if none of the enabled ContentNegotiationStrategies can determine the requested content type then 406 code (Not Acceptable) is returned. One way to avoid that; we can set a default content type to be used. In the following example, we are going to set json as default media type by using ContentNegotiationConfigurer#defaultContentType() method.

Example

Setting default content type

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

Writing Controller

@Controller
@RequestMapping("user")
public class UserController {
  
  @RequestMapping
  @ResponseBody
  public User getUserById (@RequestParam("id") long userId) {
      //creating dummy user
      User user = new User();
      user.setId(userId);
      user.setName("joe");
      user.setEmailAddress("joe@example.com");
      return user;
  }
}
@XmlRootElement
public class User implements Serializable {
  private Long id;
  private String name;
  private String password;
  private String emailAddress;
    .............
}

Adding Jackson dependency

We also need to include Jackson dependency so that MappingJackson2HttpMessageConverter can be used to produce JSON response.

pom.xml

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.8.9</version>
</dependency>

Writing JUnit tests

In this test, we are not going to use 'Accept' header, or path extension or request parameter ('format') so that our default JSON media type can be used to returned the response:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class UserTests {
  
  @Autowired
  private WebApplicationContext wac;
  private MockMvc mockMvc;
  
  @Before
  public void setup () {
      DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
      this.mockMvc = builder.build();
  }
  
  @Test
  public void testUserRequest () throws Exception {
      
      MockHttpServletRequestBuilder builder =
                MockMvcRequestBuilders.get("/user")
                                      .param("id", "100");
      
      this.mockMvc.perform(builder)
                  .andExpect(MockMvcResultMatchers.status()
                                                  .isOk())
                  .andDo(MockMvcResultHandlers.print());
  }
}

Output

mvn -q test -Dtest=UserTests#testUserRequest


MockHttpServletRequest:
HTTP Method = GET
Request URI = /user
Parameters = {id=[100]}
Headers = {}

Handler:
Type = com.logicbig.example.UserController
Method = public com.logicbig.example.User com.logicbig.example.UserController.getUserById(long)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"id":100,"name":"joe","password":null,"emailAddress":"joe@example.com"}
Forwarded URL = null
Redirected URL = null
Cookies = []

As seen in the output, we got JSON output in the body.

Note that, the browser (like Chrome) will always have XML response, that's because the browser implicitly sends multiple 'Accept' headers in the request which includes XML media type as well. That means HeaderContentNegotiationStrategy will be utilized before our default content types will be used.

Example Project

Dependencies and Technologies Used:

  • spring-webmvc 4.3.10.RELEASE: Spring Web MVC.
  • spring-test 4.3.10.RELEASE: Spring TestContext Framework.
  • javax.servlet-api 3.1.0 Java Servlet API
  • jackson-databind 2.8.9: General data-binding functionality for Jackson: works on core streaming API.
  • junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 1.8
  • Maven 3.3.9

Setting Default Content Type Example Select All Download
  • content-negotiation-default-content-type
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • MyWebConfig.java
        • test
          • java
            • com
              • logicbig
                • example

    See Also