SpringBoot自定义MessageConvert详细讲解
作者:zoeil 时间:2023-04-23 19:24:39
前言
对于页面携带的请求头中的AcceptSpringBoot有对应的10种MessageConvert可以支持写出对应的媒体类型,比如application/xml、application/json……
我们还可以通过向容器放入一个WebMvcConfigurer
实现定制化SpingMVC,自定义一个MessageConvert处理特殊的协议比如application/x-person
实现多协议数据兼容。json、xml、x-person
原理
0、@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理
1、Processor 处理方法返回值。通过 MessageConverter 处理
2、所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
3、内容协商找到最终的 messageConverter;
实现
/* 条件
*
* 1、浏览器发请求直接 返回xml [application/xml] jacksonXmlConverter
* 2、如果是ajax请求 返回json [application/json] jacksonJsonConverter
* 3、如果是app发请求,返回自定义协议数据 [application/x-person] xxxxConverter
*
* 步骤:
* 1、添加自定义的MessageConverter进系统底层
* 2、系统底层就会统计出所有MessageConverter能操作哪些类型
* 3、客户端内容协商 [person--->person]
*/
person类
@Data
public class Person {
public String username;
public Integer age;
public Pet pet;
}
pet类
@Data
public class Pet {
public String name;
public Integer age;
}
PersonMessageConvert
/*
* 自定义的Convert
*/
public class PersonMessageConvert 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);
}
/*
* @Description 服务器需要统计所有MessageConvert都能写出哪些类型,我们这里也要自定义
* @Param
**/
@Override
public List<MediaType> getSupportedMediaTypes() {
return MediaType.parseMediaTypes("application/x-person");
}
@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.getPet() + ";";
//写出去
OutputStream body = outputMessage.getBody();
body.write(data.getBytes());
}
}
方法
@ResponseBody
@GetMapping("/test/person")
public Person getPeroson() {
Person person = new Person();
person.setUsername("张三");
person.setAge(18);
person.setPet(new Pet());
return person;
}
WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new PersonMessageConvert());
}
}
}
测试
拓展
如何实现访问路径携带format参数指明协商协议
比如:http://localhost:8080/test/person?format=x-person
记得先开启基于参数的内容协商
spring:
mvc:
contentnegotiation:
favor-parameter: true
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
/*
* 自定义内容协商策略
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Map<String, MediaType> mediaTypeMap = new HashMap<>();
mediaTypeMap.put("json", MediaType.APPLICATION_JSON);
mediaTypeMap.put("xml", MediaType.APPLICATION_XML);
mediaTypeMap.put("x-person",MediaType.parseMediaType("application/x-person"));
//指定支持解析那些参数的媒体类型
ParameterContentNegotiationStrategy parametertrategy = new ParameterContentNegotiationStrategy(mediaTypeMap);
HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
configurer.strategies(Arrays.asList(parametertrategy, headerStrategy));
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new PersonMessageConvert());
}
};
}
测试
注意:有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。比如上面的ContentNegotiationConfigurer 就会覆盖原来的默认ContentNegotiationConfigurer
来源:https://blog.csdn.net/m0_62946761/article/details/128607144
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
重写Java中的equals方法介绍
新手初学Java流程控制
![](https://img.aspxhome.com/file/2023/8/77108_0s.png)
详解Java虚拟机管理的内存运行时数据区域
![](https://img.aspxhome.com/file/2023/4/81334_0s.png)
SpringCloud OpenFeign 服务调用传递 token的场景分析
![](https://img.aspxhome.com/file/2023/8/65798_0s.jpg)
Android仿UC浏览器左右上下滚动功能
![](https://img.aspxhome.com/file/2023/9/125539_0s.gif)
SpringBoot项目部署到腾讯云的实现步骤
![](https://img.aspxhome.com/file/2023/7/70557_0s.png)
git版本回退_动力节点Java学院整理
![](https://img.aspxhome.com/file/2023/4/112064_0s.png)
C#中的委托和事件详解
![](https://img.aspxhome.com/file/2023/2/113702_0s.png)
C#实现钟表程序设计
![](https://img.aspxhome.com/file/2023/1/98291_0s.jpg)
Kotlin与Java的区别详解
![](https://img.aspxhome.com/file/2023/6/75696_0s.jpg)
Android控件实现水滴效果
![](https://img.aspxhome.com/file/2023/0/130350_0s.gif)
java多线程和并发包入门示例
C#开发Winform实现文件操作案例
![](https://img.aspxhome.com/file/2023/3/102173_0s.jpg)
Java多线程程序中synchronized修饰方法的使用实例
Spring中多配置文件及引用其他bean的方式
![](https://img.aspxhome.com/file/2023/5/62715_0s.jpg)
SpringBoot Jpa分页查询配置方式解析
基于Java HashMap的死循环的启示详解
Java动态代 理分析及简单实例
C# 实现FTP客户端的小例子
![](https://img.aspxhome.com/file/2023/6/91366_0s.png)
Java运行时数据区划分原理解析
![](https://img.aspxhome.com/file/2023/9/82039_0s.png)