目录
4.2.2、自定义的uclassMessageConverter():
4.2.4、自定义组件有可能会覆盖很多默认功能,导致一些默认的功能失效。
controller层根据页面的请求,进行数据和图片的响应。
1、响应JSON,给前端返回json数据
1.1、引入依赖
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
该场景自动引入了json场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
1.2、映射方法标注@ResponseBody注解
controller层:
@Controller
public class ResponseTestController {
@ResponseBody
@GetMapping("/test/person")
public Person getPerson() {
Person person = new Person();
person.setAge(28);
person.setBirth(new Date());
person.setUserName("zhangsan");
return person;
}
}
页面响应数据:
1.3、SpringMVC支持的返回值类型
ModelAndView
Model
View
ResponseEntity
ResponseBodyEmitter
StreamingResponseBody
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
CompletionStage
WebAsyncTask
有 @ModelAttribute 注解,且为对象类型的返回值
有 @ResponseBody 注解,利用RequestResponseBodyMethodProcessor处理器进行返回
2、内容协商
根据客户端接收能力不同,返回不同媒体类型的数据。
2.1、引入xml依赖(支持返回xml格式的数据)
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
前端界面返回值:
2.2、postman分别测试返回json和xml
只需要改变请求头中Accept字段。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。
对请求头中Accept进行修改:
2.3、 开启浏览器参数方式内容协商功能
- 浏览器请求头无法修改,不能控制返回数据的格式信息
- 为了方便内容协商,开启基于请求参数的内容协商功能
- 只需要在请求中加入字段“?format=xxx”,即可改变返回给前端界面的内容格式
3.1、配置文件中开启基于浏览器参数方式内容协商功能
3.2、在请求中加入字段“?format=xxx”:
1、http://localhost:8080/test/person?format=json返回json数据给前端
2、http://localhost:8080/test/person?format=xml返回xml数据给前端
4、自定义 MessageConverter
实现多协议数据兼容。json、xml、x-guigu
-
@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理
-
Processor 处理方法返回值。通过 MessageConverter 处理
-
所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
-
内容协商找到最终的 messageConverter;
4.1、实例:需求
- 浏览器请求,返回xml;
- ajax请求返回json;
- app发送请求,返回自定义协议数据。
4.2、解决:
4.2.1步骤:
- 添加自定义的 MessageConverter 进系统底层;
- 系统底层统计出所有 MessageConverter 能操作的类型;
- 客户端内容协商。
原理:修改SpringMVC的功能。在一个入口,给容器中添加一个 WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new uclassMessageConverter());
}
};
}
4.2.2、自定义的uclassMessageConverter():
/*
自定义的converter
* */
public class uclassMessageConverter implements HttpMessageConverter<Person> {
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return clazz.isAssignableFrom(Person.class);
}
//服务器统计所有MessageConverter能写出哪些内容
//自定义数据类型
@Override
public List<MediaType> getSupportedMediaTypes() {
return MediaType.parseMediaTypes("application/x-uclass");
}
@Override
public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//自定义协议数据的写出
String data = person.getUserName() + ";" + person.getAge() + ";" + person.getBirth();
//写入输出流
OutputStream body = outputMessage.getBody();
body.write(data.getBytes());
}
}
4.2.3、自定义数据的浏览器参数方式内容协商功能
1)基于参数的内容协商策略:默认只有xml和json两种
2)自定义内容协商管理器(包括请求头和请求参数)
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//基于请求参数的内容协商管理器
Map<String, MediaType> mediaTypes = new HashMap<>();
mediaTypes.put("json", MediaType.APPLICATION_JSON);
mediaTypes.put("xml", MediaType.APPLICATION_XML);
//自定义协议
mediaTypes.put("uclass", MediaType.parseMediaType("application/x-uclass"));
//Map<String, MediaType> mediaTypes
//参数策略,需要指定支持解析url参数对应的媒体类型
ParameterContentNegotiationStrategy strategy = new ParameterContentNegotiationStrategy(mediaTypes);
//基于请求头的内容协商管理器
HeaderContentNegotiationStrategy headStrategy = new HeaderContentNegotiationStrategy();
configurer.strategies(Arrays.asList(strategy, headStrategy));
}
3)页面数据:
4)修改后的基于参数的内容协商策略:包含json、xml和uclass
4.2.4、自定义组件有可能会覆盖很多默认功能,导致一些默认的功能失效。
如上述自定义内容协商管理器中只配置参数管理器时,会导致默认的请求头协商管理器失效
需要对源码的配置和运行流程进行理解。