hutool json转map_记一个Jackson与Hutool混用的坑

在升级Hutool至4.6.8后,使用Feign调用出现错误,原因是Hutool的JSONNull与Jackson的序列化冲突。解决方案是避免直接将Hutool的JSONObject作为Map参数传递,而是使用DTO进行数据封装。总结经验,建议避免混合使用不同JSON库,以防处理JSON时出现问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0ba2f0bff9718e781e2d9c61a551d1b5.png
技术公众号: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值