美文网首页Java
记一个Jackson与Hutool混用的坑

记一个Jackson与Hutool混用的坑

作者: SevenLin1993 | 来源:发表于2019-10-18 23:06 被阅读0次

    技术公众号:Java In Mind(Java_In_Mind),欢迎关注!

    问题出现

    最近遇到一个问题,Hutool从4.1.7升级到4.6.8之后,使用feign调用出现错误:

    ...
    Caused by: feign.codec.EncodeException: Type definition error: [simple type, class cn.hutool.json.JSONNull]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class cn.hutool.json.JSONNull and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: cn.hutool.json.JSONObject["securityGroupIds"])
        at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:349)
        at feign.ReflectiveFeign$BuildTemplateByResolvingArgs.create(ReflectiveFeign.java:213)
        at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:72)
        at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108)
        at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)
        at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)
        at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
        ... 29 more
    Caused by: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class cn.hutool.json.JSONNull]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class cn.hutool.json.JSONNull and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: cn.hutool.json.JSONObject["securityGroupIds"])
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:295)
        at org.springframework.http.converter.AbstractGenericHttpMessageConverter.writeInternal(AbstractGenericHttpMessageConverter.java:111)
        at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:226)
        at org.springframework.cloud.openfeign.support.SpringEncoder.encode(SpringEncoder.java:94)
        at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:345)
        ... 35 more
    Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class cn.hutool.json.JSONNull and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: cn.hutool.json.JSONObject["securityGroupIds"])
        at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
        at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
        at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:312)
        at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
        at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
        at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:718)
        at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:639)
        at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:33)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
        at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
        at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913)
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:288)
        ... 39 more
    

    问题分析

    Hutool会使用JSONNull来表示空值,而SpringCloud Feign默认使用的序列化是Jackson,在远程调用的过程中使用了Map,直接传入了Hutool的JSONObject,而该Map存在空值,所以存在JSONNull,最终导致错误。

    问题解决

    使用DTO传递参数,总之就是不要直接把JSONObjct作为参数传递。

    总结

    在使用JSON序列化工具的时候,尽量不要混合使用,即使存在多个JSON工具,也不把一个JSON工具的JSON对象直接用另一个JSON工具来处理,因为每个JSON工具都有自己的对JSON的处理,包括一些优化,如果混着用就会出问题,所以,在使用JSON工具处理JSON的时候不要混着使用多种JSON

    吐槽

    这里吐槽下Hutool,null值处理的时候要小心,非空判断用JSONObject.isNull,不要自行处理:

    String jsonStr = "{\"name\":\"seven\",\"password\":null}";
    
    JSONObject json = new JSONObject(jsonStr);
    System.out.println(json.get("password")==null);
    System.out.println(json.get("password").getClass());
        
    Map<String,String> map = new JSONObject(jsonStr).toBean(Map.class);
    System.out.println(map.get("password")==null);
    System.out.println(map.get("password").getClass());
    
    System.out.println(json.isNull("password"));
    
    // 结果
    false
    class cn.hutool.json.JSONNull
    false
    class cn.hutool.json.JSONNull
    true
    

    相关文章

      网友评论

        本文标题:记一个Jackson与Hutool混用的坑

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