简单聊一聊HttpMessageConverter
org.springframework.http.converter.HttpMessageConverter
技术背景
问题点
项目重构,表结构重构,主键从自增id换成了 雪花算法生成的id。雪花算法生成的id是19位的,但是js超过16位就会出现精度损失,导致拿到的id不准确。
简单解决
后端将Long类型转成String传给前端,简单粗暴,十分有效,但是不优雅,而且要伴随着多次类型转化。
统一处理
Spring Framework里有个类,叫HttpMessageConverter,全路径是org.springframework.http.converter.HttpMessageConverter
,这个类是spring-web项目里面的,我们看一下这个接口在spring-web项目里的位置
-org.springframework
- http
- client
- server
- remoting
- web
- converter
- feed
- json
- protobuf
- support
- xml
- org.springframework.http.converter.HttpMessageConverter
这个类能做什么
看一下这个接口的接口定义Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
即:策略接口,能定义一个转换器,实现HTTP requests 到responses之间的互相转换。总计只有5个方法
这5个方法大致了解一下就行,主要是读写相关,即和序列化和反序列化相关的。
回到正题,如何优雅的解决这个前面的js精度损失的问题呢,spring-mvc的默认序列化框架时jackson,jackson对HttpMessageConverter的实现类是org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
我们可以通过这个实现类来重写spring-mvc的默认实现,主要实现办法还是利用我们的万能百宝箱WebMvcConfigurationSupport
这个类,重写他的方法
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(jackson2HttpMessageConverter);
}
在反序列化的时候统一转换
转换出来的id主动转了String