别了,阿里巴巴fastjson!企业项目迁移Gson全攻略( 三 )

看得出,两者区别主要在get各种类型上,Gson调用方法有所改变,但是变化不大 。
那么,来看下空对象反序列化会不会出现异常:
String jsonObjectEmptyCase = "{}";// fastjsonJSONObject jsonObjectEmpty = JSON.parseobject(jsonObjectEmptyCase);System.out.println(jsonObjectEmpty);System.out.println(jsonObjectEmpty.size());// 输出:// {}// 0// GsonJsonObject jsonObjectGsonEmpty = gson.fromJson(jsonObjectEmptyCase, JsonObject.class);System.out.println(jsonObjectGsonEmpty);System.out.println(jsonObjectGsonEmpty.size());// 输出:// {}// 0没有异常,开心 。
看看空数组呢,毕竟[]感觉比{}更加容易出错 。
String jsonArrayEmptyCase = "[]";// fastjsonJSONArray jsonArrayEmpty = JSON.parseArray(jsonArrayEmptyCase);System.out.println(jsonArrayEmpty);System.out.println(jsonArrayEmpty.size());// 输出:// []// 0// GsonJsonArray jsonArrayGsonEmpty = gson.fromJson(jsonArrayEmptyCase, JsonArray.class);System.out.println(jsonArrayGsonEmpty);System.out.println(jsonArrayGsonEmpty.size());// 输出:// []// 0两个框架也都没有问题,完美解析 。
范型处理解析泛型是一个非常常用的功能,我们项目中大部分fastjson代码就是在解析json和Java Bean 。
// 实体类User user = new User();user.setId(1L);user.setUserName("马云");// fastjsonList<User> userListResultFastjson = JSONArray.parseArray(JSON.toJSONString(userList), User.class);List<User> userListResultFastjson2 = JSON.parseObject(JSON.toJSONString(userList), new TypeReference<List<User>>(){});System.out.println(userListResultFastjson);System.out.println("userListResultFastjson2" + userListResultFastjson2);// 输出:// userListResultFastjson[User [Hash = 483422889, id=1, userName=马云], null]// userListResultFastjson2[User [Hash = 488970385, id=1, userName=马云], null]// GsonList<User> userListResultTrue = gson.fromJson(gson.toJson(userList), new TypeToken<List<User>>(){}.getType());System.out.println("userListResultGson" + userListResultGson);// 输出:// userListResultGson[User [Hash = 1435804085, id=1, userName=马云], null]可以看出,Gson也能支持泛型 。
List/Map写入这一点fastjson和Gson有区别,Gson不支持直接将List写入value,而fastjson支持 。
所以Gson只能将List解析后,写入value中,详见如下代码:
// 实体类User user = new User();user.setId(1L);user.setUserName("马云");// fastjsonJSONObject jsonObject1 = new JSONObject();jsonObject1.put("user", user);jsonObject1.put("userList", userList);System.out.println(jsonObject1);// 输出:// {"userList":[{"id":1,"userName":"马云"},null],"user":{"id":1,"userName":"马云"}}// GsonJsonObject jsonObject = new JsonObject();jsonObject.add("user", gson.toJsonTree(user));System.out.println(jsonObject);// 输出:// {"user":{"id":1,"userName":"马云"},"userList":[{"id":1,"userName":"马云"},null]}如此一来,Gson看起来就没有fastjson方便,因为放入List是以gson.toJsonTree(user)的形式放入的 。这样就不能先入对象,在后面修改该对象了 。(有些同学比较习惯先放入对象,再修改对象,这样的代码就得改动)
驼峰与下划线转换驼峰转换下划线依靠的是修改Gson的序列化模式,修改为LOWER_CASE_WITH_UNDERSCORES
GsonBuilder gsonBuilder = new GsonBuilder();gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);Gson gsonUnderScore = gsonBuilder.create();System.out.println(gsonUnderScore.toJson(user));// 输出:// {"id":1,"user_name":"马云"}常见问题排雷下面整理了我们在公司项目迁移Gson过程中,踩过的坑,这些坑现在写起来感觉没什么技术含量 。但是这才是我写这篇文章的初衷,帮助大家把这些很难发现的坑避开 。
这些问题有的是在测试进行回归测试的时候发现的,有的是在自测的时候发现的,有的是在上线后发现的,比如Swagger挂了这种不会去测到的问题 。
Date序列化方式不同不知道大家想过一个问题没有,如果你的项目里有缓存系统,使用fastjson写入的缓存,在你切换Gson后,需要用Gson解析出来 。所以就一定要保证两个框架解析逻辑是相同的,但是,显然这个愿望是美好的 。


推荐阅读