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());
           }
      }
   }

测试

SpringBoot自定义MessageConvert详细讲解

SpringBoot自定义MessageConvert详细讲解

拓展

如何实现访问路径携带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());
           }
       };
   }

测试

SpringBoot自定义MessageConvert详细讲解

SpringBoot自定义MessageConvert详细讲解

SpringBoot自定义MessageConvert详细讲解

注意:有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。比如上面的ContentNegotiationConfigurer 就会覆盖原来的默认ContentNegotiationConfigurer

来源:https://blog.csdn.net/m0_62946761/article/details/128607144

标签:SpringBoot,自定义,MessageConvert
0
投稿

猜你喜欢

  • 重写Java中的equals方法介绍

    2023-06-24 00:30:26
  • 新手初学Java流程控制

    2023-08-23 08:12:34
  • 详解Java虚拟机管理的内存运行时数据区域

    2023-12-04 01:32:35
  • SpringCloud OpenFeign 服务调用传递 token的场景分析

    2022-12-26 22:24:07
  • Android仿UC浏览器左右上下滚动功能

    2023-08-27 12:43:19
  • SpringBoot项目部署到腾讯云的实现步骤

    2023-01-01 16:58:55
  • git版本回退_动力节点Java学院整理

    2022-06-21 13:26:10
  • C#中的委托和事件详解

    2022-01-20 01:31:53
  • C#实现钟表程序设计

    2023-01-01 06:38:42
  • Kotlin与Java的区别详解

    2023-06-22 16:25:58
  • Android控件实现水滴效果

    2021-07-31 20:43:51
  • java多线程和并发包入门示例

    2022-05-10 12:29:34
  • C#开发Winform实现文件操作案例

    2022-04-28 15:30:53
  • Java多线程程序中synchronized修饰方法的使用实例

    2022-05-08 16:38:56
  • Spring中多配置文件及引用其他bean的方式

    2023-07-01 17:31:03
  • SpringBoot Jpa分页查询配置方式解析

    2023-03-02 10:04:02
  • 基于Java HashMap的死循环的启示详解

    2021-08-15 20:01:16
  • Java动态代 理分析及简单实例

    2023-11-24 21:14:56
  • C# 实现FTP客户端的小例子

    2022-06-09 13:19:13
  • Java运行时数据区划分原理解析

    2023-07-13 22:05:48
  • asp之家 软件编程 m.aspxhome.com