一直以來, 我都很喜歡Google家出品的工具類, 比如Guava, Gson等, 但是在實(shí)際項(xiàng)目中, 使用Gson遇到了一些問題.
問題
1. 如果使用Gson作為HttpMessageConverter消息解析器, swagger會(huì)引起沖突導(dǎo)致無法正常工作
使用Gson作為序列化的實(shí)現(xiàn)后,和swagger的json類序列化會(huì)出現(xiàn)沖突, 導(dǎo)致訪問swagger頁面的時(shí)候會(huì)出現(xiàn) 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()); } }
將適配器配置到消息轉(zhuǎn)換器中
@Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Gson gson = new GsonBuilder() .enableComplexMapKeySerialization() // 將適配器配置到消息轉(zhuǎn)換器中 .registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter()) .create(); converters.add(new GsonHttpMessageConverter(gson)); super.configureMessageConverters(converters); }
訪問swagger, 問題解決.
2. Gson在將json字符串轉(zhuǎn)換為實(shí)體類中Object類型屬性的時(shí)候, Integer類型會(huì)被默認(rèn)轉(zhuǎn)換為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);
// 輸出結(jié)果: 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的數(shù)值類型被轉(zhuǎn)換為了浮點(diǎn)型, 跟期望的結(jié)果不一致.
目前網(wǎng)絡(luò)上已經(jīng)有很多文章提出了原理分析解決方案, 如果大家想要了解, 可以自行搜索關(guān)鍵字: "Gson轉(zhuǎn)換Int變?yōu)镈ouble類型", 此處不再贅述.
解決方案
網(wǎng)絡(luò)上相應(yīng)修改源碼的方式
-
使用阿里巴巴的
fastjson
這也是我選擇替換方案, 同上數(shù)據(jù)測試效果如下:
@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); }
可以看到, 該問題解決.
后記
雖然針對各種問題都有相應(yīng)的解決辦法, 但是在項(xiàng)目中能出現(xiàn)多次意外的問題, 令我對此還是不太放心. 所以 在沒有必要的情況下, 我是不會(huì)選擇Gson再作為我的Json工具庫.