数据响应与内容协商
1、响应JSON
1.1、jackson.jar+@ResponseBody
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
web场景自动引入了json场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
package com.wenliang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.wenliang.bean.Person;
import java.util.Date;
@Controller
public class ResponseTestController {
@ResponseBody
@GetMapping("/test/person")
public Person getPerson(){
Person person = new Person();
person.setAge(20);
person.setBirth(new Date());
person.setUserName("ayan");
return person;
}
}
给前端自动返回json数据;
2、内容协商
根据客户端接收能力不同,返回不同媒体类型的数据。
1、引入xml依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
2、postman分别测试返回json和xml
只需要改变请求头中Accept字段。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。
3、开启浏览器参数方式内容协商功能
为了方便内容协商,开启基于请求参数的内容协商功能。
spring:
contentnegotiation:
favor-parameter: true #开启请求参数内容协商模式
发请求:
http://localhost:8080/test/person?format=json
http://localhost:8080/test/person?format=xml
4、自定义 MessageConverter
实现多协议数据兼容。json、xml、x-guigu
0、@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理
1、Processor 处理方法返回值。通过 MessageConverter 处理
2、所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
3、内容协商找到最终的 messageConverter
SpringMVC的什么功能。一个入口给容器中添加一个 WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
}
}
package com.wenliang.converter;
import com.wenliang.bean.Person;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
public class AyanMessageConverter implements HttpMessageConverter<Person> {
@Override
public boolean canRead(Class<?> aClass, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> aClass, MediaType mediaType) {
return false;
}
/**
* 服务器要统计所有MessageConverter都能写出哪些内容类型
* application/x-ayan
* @return
*/
@Override
public List<MediaType> getSupportedMediaTypes() {
return MediaType.parseMediaTypes("application/x-ayan");
}
@Override
public Person read(Class<? extends Person> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public void write(Person person, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
//自定义协议数据的写出
String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();
//写出去
OutputStream body = httpOutputMessage.getBody();
body.write(data.getBytes());
}
}
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new AyanMessageConverter());
}
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// Map<string, MediaType> mediaTypes
Map<String, MediaType> mediaTypes = new HashMap<>();
mediaTypes.put("json",MediaType.APPLICATION_JSON);
mediaTypes.put("xml",MediaType.APPLICATION_XML);
mediaTypes.put("aa",MediaType.parseMediaType("application/x-ayan"));
//指定支持解析哪些参数对应的哪些媒体类型
ParameterContentNegotiationStrategy parametercontentNegotiationstrategy = new ParameterContentNegotiationStrategy(mediaTypes);
HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
configurer.strategies(Arrays.asList(headerStrategy,parametercontentNegotiationstrategy));
}
有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。
大家考虑,上述功能除了我们完全自定义外?SpringBoot有没有为我们提供基于配置文件的快速修改媒体类型功能?怎么配置呢?【提示:参照SpringBoot官方文档web开发内容协商章节】