SpringBoot自定义MessageConvert详细讲解
前言
对于页面携带的请求头中的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
到此这篇关于SpringBoot自定义MessageConvert详细讲解的文章就介绍到这了,更多相关SpringBoot MessageConvert内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解SpringBoot中添加@ResponseBody注解会发生什么
这篇文章主要介绍了详解SpringBoot中添加@ResponseBody注解会发生什么,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-11-11Skywalking改成适配阿里云等带Http Basic的Elasticsearch服务
这篇文章主要介绍了改造Skywalking支持阿里云等带Http Basic的Elasticsearch服务2022-02-02Java同步锁Synchronized底层源码和原理剖析(推荐)
这篇文章主要介绍了Java同步锁Synchronized底层源码和原理剖析,释放后,进入减减操作、直到为0然后唤醒队列,让他们去争夺锁,循环前面步骤,对Java同步锁Synchronized相关知识感兴趣的朋友一起看看吧2022-05-05SpringBoot的@Value给静态变量注入application.properties属性值
这篇文章主要介绍了SpringBoot的@Value给静态变量注入application.properties属性值,Spring是一个开源的框架,主要是用来简化开发流程,通过IOC,依赖注入(DI)和面向接口实现松耦合,需要的朋友可以参考下2023-05-05
最新评论