想要解决的问题
本人在之前进行springboot开发时偶然发现,springboot会默认将返回前端的响应结果字段名小写。如下是定义的返回类型:
static class MyReturnValue{
private String Name;
private String Word;
}
postman 客户端最终看到的看到的返回结果如下:
{
"name": "张伟",
"word": "张伟真伟大"
}
我们想要解决的问题是:保证序列化之后的返回值与Java类定义中的字符一致。上网查了一下资料发现可以通过往属性上添加 @JSONField 注解的办法来指定序列化之后的字段名。是可以这么做,但是字段多的话就不太方便了。所以我想通过本篇博客记录一下定制序列化转换器的方法来看看能不能处理这个问题。
定制 HttpMessageConverter
定制一个 HttpMessageConveter 很简单,继承抽象类 AbstractHttpMessageConverter,实现其中的 canRead,canWrite,writeInternal,readInternal 等几个方法就可以。需要注意的是直接实现 HttpMessageConverter 应用启动会报错。
public class NoCaseHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
protected boolean supports(Class<?> clazz) {
return true;
}
protected boolean canRead(@Nullable MediaType mediaType) {
return false; // false,参数解析时不会进入 readInternal方法
}
protected boolean canWrite(@Nullable MediaType mediaType) {
return true; // true,则序列化会进入 writeInternal 方法
}
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return new Object();
}
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
byte[] result = JSON.toJSONBytes(o, SerializerFeature.BrowserCompatible, SerializerFeature.BrowserSecure);
outputMessage.getBody().write(result);
}
}
注入converts配置
除了定义,还需要想办法把定制的Converter 注入到 web 配置中去。可以通过实现 WebMvcConfigurer 这个接口 extendMessageConverters 来实现,代码如下:
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class MyWebMvcConfigurer implements WebMvcConfigurer {
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0,new NoCaseHttpMessageConverter());
}
}
我在新的Converter中,用阿里的 fastJson 来进行序列化,查阅资料后通过加上如下配置,即可取消自动转小写。
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
TypeUtils.compatibleWithFieldName = true;
byte[] result = JSON.toJSONBytes(o, SerializerFeature.BrowserCompatible, SerializerFeature.BrowserSecure);
outputMessage.getBody().write(result);
}
请求测试接口,看一下返回结果:
{
"Name": "张伟",
"Word": "张伟真伟大"
}
完美解决了这个问题。