背景:
昨天在调试接口的时候总是报错,服务的截图错误信息为: java.lang.Integer cannot be cast to java.lang.Long
分析:
我写的是一个通用服务,接受数据的时候,jackson框架将json里面的对象数据用Map<String,Object>来接,我们也知道json是没有long类型的概念的,比如我传入的数据:
{ "value1": "12345", "value2": 67890 }
尽管我java类原本认为value2是Long类型,但是跑到json里面之后,他就只能变成这种不带引号的数值。
反解析成java对象之后,可能这个Long类型就丢了。
解决:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer; import java.io.IOException; import java.util.List; import java.util.Map; public class CustomDeserializer extends JsonDeserializer<Object> { private final UntypedObjectDeserializer delegate; public CustomDeserializer() { this.delegate = new UntypedObjectDeserializer(null, null); } @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Object m = delegate.deserialize(p, ctxt); return recursivelyProcessValue(m); } private Object recursivelyProcessValue(Object value) { if (value instanceof Map) { Map<String, Object> map = (Map<String, Object>) value; for (Map.Entry<String, Object> entry : map.entrySet()) { entry.setValue(recursivelyProcessValue(entry.getValue())); } } else if (value instanceof List) { List<Object> list = (List<Object>) value; for (int i = 0; i < list.size(); i++) { list.set(i, recursivelyProcessValue(list.get(i))); } } else if (value instanceof String) { String strValue = (String) value; if (strValue.startsWith("@JSON_TYPE_LONG:")) { Long longValue = Long.parseLong(strValue.substring("@JSON_TYPE_LONG:".length())); return longValue; } } return value; } }
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Object.class, new CustomDeserializer ()); objectMapper.registerModule(module); return objectMapper; } }
这样我们只需要将long类型的字段的值写成格式类似:”@JSON_TYPE_LONG:12345″ 的形式就行了。
或者为了稳妥起见,你可以将Jackson框架转换过后的对象根据你的需要将他用recursivelyProcessValue函数处理一下就行了,这个函数会递归找值满足条件的进行修改。