SpringBoot添加自定义HttpMessageConverter

1,332 阅读1分钟

为什么需要自定义MessageConverter,当我们想要让一些数据以我们自定义的格式返回,而不是普通的json或xml格式的数据。并且底层的最终是遍历MessageConverter,然后再进行数据转换的。

首先需要创建一个自己的HttpMessageConverter,代码如下

public class MyMessageConverter implements HttpMessageConverter<Pet> {

    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return false;
    }
    //Pet只是用来测试的一个pojo类
    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Pet.class);
    }
   //设置能够转换的媒体类型
    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes("application/mydata");
    }

    @Override
    public List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
        return HttpMessageConverter.super.getSupportedMediaTypes(clazz);
    }

    @Override
    public Pet read(Class<? extends Pet> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    @Override
    public void write(Pet pet, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        OutputStream body = outputMessage.getBody();
        String myout="测试数据"+pet.getName()+pet.getAge();
        body.write(myout.getBytes());
    }
}

然后再将我们的自定义的HttpMessageConverter丢到我们的springmvc容器中,一般这种都是通过 WebMvcConfigurer来添加的,代码如下

@Configuration
public class MyMessageConverterConfig {

    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new MyMessageConverter());
            }
        };

    }
}

需要注意 这种情况只能处理设置了请求头accept为自定义媒体类型的情况(这里我们设置的是application/mydata)

如果想通过添加请求参数format来修改数据的返回类型的话,可以采用下面的方法

//自定义strategies,注意上面的代码也依旧要保留,因为最终的处理还是上面的HttpMessageConverter
@Configuration
public class MyMessageConverterConfig {

    @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("mydata", MediaType.parseMediaType("application/mydata"));
                ParameterContentNegotiationStrategy strategys = new ParameterContentNegotiationStrategy(mediaTypes);
                //不加header的话,在没有format的情况下,不管accept是什么值都会返回json数据
                HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
                configurer.strategies(Arrays.asList(strategys,headerStrategy));
            }

            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new MyMessageConverter());
            }
        };

    }
}

添加之后,底层的strategies如下

Snipaste_2021-10-29_15-07-41.png

默认的如下

Snipaste_2021-10-29_15-09-58.png