bug日记:2020年11月5日
项目场景:
springcloud的微服务项目
问题描述:
其中一个支撑服务整体不可解析响应数据
原因分析:
1.可能是全局拦截器 2.可能是全局配置解决方案:
今天收到一个bug,前端解析json对象异常,检查了接口响应数据,均返回如下格式:
"{\"msg\":\"操作成功\",\"code\":\"200\",\"data\":\"123456\"}"
正确的格式应该是
{"msg":"操作成功","code":"200","data":"123456"}
如上两种数据格式,明显异常数据发生了二次序列化的现象,伙伴经过询问是否有人修改过相关业务代码的,均未有相关修改操作。
那么,首先检查代码,是否存在二次序列化的问题,经过反复检查,多次确认,代码上不存在二次序列化的操作,而且一点问题没有,在控制台中打印出来的数据却是正常的格式,而响应的数据格式却不正常,但是有人跟我提到只有那一个服务,服务里的所有接口响应数据均不是正常格式。
那么,是不是存在拦截器对响应数据做了操作,或者是进行了全局配置呢?
经过两三分钟的排查,检查到有人实现了WebMvcConfigurer接口,WebMvcConfigurer这个接口是干嘛的呢?
我们查看源码,里面有这么一段话来描述这个接口
/**
* Defines callback methods to customize the Java-based configuration for
* Spring MVC enabled via {@code @EnableWebMvc}.
*
* <p>{@code @EnableWebMvc}-annotated configuration classes may implement
* this interface to be called back and given a chance to customize the
* default configuration.
*
* @author Rossen Stoyanchev
* @author Keith Donald
* @author David Syer
* @since 3.1
*/
根据这段话的描述,WebMvcConfigurer接口是用于以java方式来做配置的接口,该接口可以用于拦截器、消息转换器等功能,但是重要的一点是,这个配置生效的是全局的。
再继续检查发现了如下这段话
@Bean
public HttpMessageConverters fastJsonConverters() {
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastJsonConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> httpMessageConverter = fastJsonConverter;
return new HttpMessageConverters(httpMessageConverter);
}
这段话使得当前服务自定义了全局消息转换器,并且是在返回的原有数据上再进行了一次的序列化,这么写的原因是有伙伴想格式化日期类型,但是在之前我便提醒了一下,前后端交互日期类型的数据最好是字符串而不是整个日期对象
这个bug的感想:日期在不同语言下的计算方式是不一样的,但是json和xml是多语言之间传输数据的通用的,几乎在开发过程中所有语言都是支持的,因此在开发过程中不建议直接传输日期对象,而是根据规定的格式的日期字符串,另一个就是设计到钱的数据,合理的方式在java中用什么类型呢?在传输的过程中又是什么样的类型呢?这个也是值得注意的一点的,不然整个项目会面临巨大的烦恼,和杂乱的代码