引言
在Spring MVC框架中,处理客户端请求时,内容协商是一个关键的步骤。如果服务器无法确定客户端请求的内容类型,将返回一个406 Not Acceptable响应。本文将探讨如何通过设置默认内容类型来避免这种情况,并展示一个具体的实例。
设置默认内容类型
在Spring MVC中,我们可以通过ContentNegotiationConfigurer
接口的defaultContentType()
方法来设置默认内容类型。以下是一个将JSON设置为默认媒体类型的配置示例:
@EnableWebMvc
@ComponentScan
public class MyWebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}
控制器编写
接下来,我们需要编写一个控制器来处理用户请求。以下是一个简单的用户控制器示例:
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping
public User getUserById(@RequestParam("id") long userId) {
// 创建虚拟用户
User user = new User();
user.setId(userId);
user.setName("joe");
user.setEmailAddress("joe@example.com");
return user;
}
}
添加Jackson依赖
为了使用MappingJackson2HttpMessageConverter
来生成JSON响应,我们需要在项目的pom.xml
文件中添加Jackson依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
编写JUnit测试
在测试中,我们将不使用’Accept’头,路径扩展或请求参数(‘format’),以便使用默认的JSON媒体类型返回响应:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyWebConfig.class)
public class UserTests {
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());
}
}
测试输出
运行测试命令mvn -q test -Dtest=UserTests#testUserRequest
,我们可以看到以下输出:
- HTTP方法:GET
- 请求URI:/user
- 参数:{id=[100]}
- 响应状态:200
- 响应头:Content-Type=[application/json;charset=UTF-8]
- 响应体:{“id”:100,“name”:“joe”,“password”:null,“emailAddress”:“joe@example.com”}
结论
通过设置默认内容类型,我们可以有效地避免Spring MVC在无法确定请求内容类型时返回406 Not Acceptable响应。在本例中,我们通过配置将JSON设置为默认媒体类型,并展示了如何编写控制器和JUnit测试来验证这一行为。
示例项目技术栈
- Spring Web MVC 4.3.10.RELEASE
- Spring TestContext Framework 4.3.10.RELEASE
- Java Servlet API 3.1.0
- Jackson Databind 2.8.9
- JUnit 4.12
- JDK 1.8
- Maven 3.3.9