美文网首页经典好文
我为什么在项目中弃用Gson

我为什么在项目中弃用Gson

作者: 视频怪物 | 来源:发表于2019-11-26 16:30 被阅读0次

    一直以来, 我都很喜欢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工具库.

    工具类链接

    基于Gson封装的Java json工具类

    基于fastjson封装的Java json工具类

    相关文章

      网友评论

        本文标题:我为什么在项目中弃用Gson

        本文链接:https://www.haomeiwen.com/subject/bcgewctx.html