我为什么在项目中弃用Gson

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。