SpringBoot自定义MessageConvert

导读:本篇文章讲解 SpringBoot自定义MessageConvert,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

前言

原理

实现

拓展


前言

对于页面携带的请求头中的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都能写出哪些类型,我们这里也要自定义
     * @Author zoe
     * @Date 2023/1/8 22:54
     * @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://www.bmabk.com/index.php/post/118452.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!