为什么需要自定义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如下
默认的如下