一、简介
内容类型指示如何解释请求/响应中存在的数据。每当控制器收到 Web 请求时,它就会消耗或生成一些媒体类型。在此请求-响应模型中,可以使用/生成多种媒体类型,JSON 就是其中之一。
在这个快速教程中,我们将探索使用 Spring Boot 在 Spring MVC 中设置内容类型的不同方法。
2.Spring中的 @RequestMapping
简单来说, @RequestMapping 是一个重要的注解,它将Web请求映射到Spring控制器。它具有各种属性,包括 HTTP 方法、请求参数、标头和媒体类型。
一般来说,媒体类型分为两类:可消耗的和可生产的。除了这些之外,我们还可以在 Spring 中定义自定义媒体类型。 主要目的是将主要映射限制为我们的请求处理程序的媒体类型列表。
2.1.耗材类型
使用 Consumers 属性,我们可以指定控制器将从客户端接受的媒体类型。我们也可以提供媒体类型列表。让我们定义一个简单的端点:
@RequestMapping(value = "/greetings", method = RequestMethod.POST, consumes="application/json")
public void addGreeting(@RequestBody ContentType type, Model model) {
// code here
}
如果客户端指定了无法被资源消耗的媒体类型,系统将生成 HTTP“415 不支持的媒体类型”错误。
2.2.可制作的媒体类型
与 Consumers 属性相反, Produces 指定资源可以生成并发送回客户端的媒体类型。毫无疑问,我们可以使用选项列表。 如果资源无法生成所请求的资源,系统将生成 HTTP“406 Not Acceptable”错误。
让我们从公开 JSON 字符串的 API 的简单示例开始。
这是我们的端点:
@GetMapping(
value = "/greetings-with-response-body",
produces="application/json"
)
public String getGreetingWhileReturnTypeIsString() {
return "{\"test\": \"Hello\"}";
}
我们将使用 CURL 进行测试:
curl http://localhost:8080/greetings-with-response-body
上述命令产生响应:
{ "test": "Hello" }
3. 使用 Spring Boot 来休息控制器
如果我们使用 Spring Boot 作为其余控制器,那么通过处理多个事情的单个注释将使我们的生活变得轻松。 @RestController 注释将 @Controller 和 @ResponseBody 注释合并为一个注释。这将应用于该类中定义的所有端点。
3.1.使用@RestController注解
Jackson ObjectMapper 类从字符串、流或文件中解析 JSON。如果 Jackson 位于类路径上,则 Spring 应用程序中的任何控制器默认都会呈现 JSON 响应。
我们将添加一个单元测试来验证响应:
@Test
public void givenReturnTypeIsString_whenJacksonOnClasspath_thenDefaultContentTypeIsJSON()
throws Exception {
// Given
String expectedMimeType = "application/json";
// Then
String actualMimeType = this.mockMvc.perform(MockMvcRequestBuilders.get("/greetings-with-response-body", 1))
.andReturn().getResponse().getContentType();
Assert.assertEquals(expectedMimeType, actualMimeType);
}
3.2.使用 响应实体
与 @ResponseBody 相比, ResponseEntity 是表示整个 HTTP 响应的通用类型。因此,我们可以控制其中的任何内容:状态代码、标头和正文。
让我们定义一个新的端点:
@GetMapping(
value = "/greetings-with-response-entity",
produces = "application/json"
)
public ResponseEntity<String> getGreetingWithResponseEntity() {
final HttpHeaders httpHeaders= new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>("{\"test\": \"Hello with ResponseEntity\"}", httpHeaders, HttpStatus.OK);
}
在浏览器的开发者控制台中,我们可以看到以下响应:
{"test": "Hello with ResponseEntity"}
我们将使用测试用例验证响应的内容类型:
@Test
public void givenReturnTypeIsResponseEntity_thenDefaultContentTypeIsJSON() throws Exception {
// Given
String expectedMimeType = "application/json";
// Then
String actualMimeType = this.mockMvc.perform(MockMvcRequestBuilders.get("/greetings-with-response-entity", 1))
.andReturn().getResponse().getContentType();
Assert.assertEquals(expectedMimeType, actualMimeType);
}
3.3.使用 Map<String, Object> 返回类型
最后但并非最不重要的一点是,我们还可以通过将返回类型从 String 更改为 Map 来设置内容类型。此 Map 返回类型将需要封送,并返回一个 JSON 对象。
这是我们的新端点:
@GetMapping(
value = "/greetings-with-map-return-type",
produces = "application/json"
)
public Map<String, Object> getGreetingWhileReturnTypeIsMap() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("test", "Hello from map");
return map;
}
让我们看看实际效果:
curl http://localhost:8080/greetings-with-map-return-type
curl 命令返回 JSON 响应:
{ "test": "Hello from map" }
4。结论
在本文中,我们学习了如何使用 Spring boot 在 Spring MVC 中设置内容类型,首先是类路径中的默认 Json 映射器,然后使用 ResponseEntity,最后将返回类型从 String 更改为 Map。
与往常一样,所有代码片段都可以在 GitHub 上找到。