一直以来, 我都很喜欢Google家出品的工具类, 比如Guava, Gson等, 但是在实际项目中, 使用Gson遇到了一些问题.
问题
1. 如果使用Gson作为HttpMessageConverter消息解析器, swagger会引起冲突导致无法正常工作
使用Gson作为序列化的实现后,和swagger的json类序列化会出现冲突, 导致访问swagger页面的时候会出现 No operations defined in spec!
解决方案:
不使用Gson作为HttpMessageConverter
-
为GsonHttpMessageConverter做适配器, 专门处理Json序列化问题
定义swagger适配器
SpringfoxJsonToGsonAdapter
public class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> { @Override public JsonElement serialize(Json json, Type type, JsonSerializationContext context) { final JsonParser parser = new JsonParser(); return parser.parse(json.value()); } }
将适配器配置到消息转换器中
@Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Gson gson = new GsonBuilder() .enableComplexMapKeySerialization() // 将适配器配置到消息转换器中 .registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter()) .create(); converters.add(new GsonHttpMessageConverter(gson)); super.configureMessageConverters(converters); }
访问swagger, 问题解决.
2. Gson在将json字符串转换为实体类中Object类型属性的时候, Integer类型会被默认转换为Double型
测试代码:
@Slf4j
public class Tests {
@Data
@NoArgsConstructor
@AllArgsConstructor
private static class BizData {
private String version;
private Object props;
}
@Test
public void parse() {
BizData bizData = new GsonBuilder().create().fromJson(testData(), BizData.class);
// 输出结果: Tests.BizData(version=1.0.0, props={count=30.0, rate=12.3})
log.info(bizData);
}
private String testData() {
return return "{\"version\" : \"1.0.0\", \"props\" : {\"count\" : 30, \"rate\": 12.3}}";
}
}
可以很明显看出: count的数值类型被转换为了浮点型, 跟期望的结果不一致.
目前网络上已经有很多文章提出了原理分析解决方案, 如果大家想要了解, 可以自行搜索关键字: "Gson转换Int变为Double类型", 此处不再赘述.
解决方案
网络上相应修改源码的方式
-
使用阿里巴巴的
fastjson
这也是我选择替换方案, 同上数据测试效果如下:
@Test public void parse() { BizData bizData = JSON.parseObject(testData(), BizData.class); // Test.BizData(version=1.0.0, props={"rate":12.3,"count":30}) log.info(bizData); }
可以看到, 该问题解决.
后记
虽然针对各种问题都有相应的解决办法, 但是在项目中能出现多次意外的问题, 令我对此还是不太放心. 所以 在没有必要的情况下, 我是不会选择Gson再作为我的Json工具库.