![15a92ef6714f7f788b1d22c26580e7fb.png](https://i-blog.csdnimg.cn/blog_migrate/008829fbc49d2eb8914dc13e05c8651a.jpeg)
jackson解析未知属性异常
今天测试同学反馈,测试环境订单信息无法查看了。一开始以为是网络问题,没注意,对方说尝试了几次还是一样的错误。我看了眼日志,发觉json解析出错了。出错也很明显,jackson解析时出现了未知的属性 lid,造成解析失败。
跟对方确认后,的确是测试环境新增参数返回了。按理说,这样不影响业务的参数,是不应该造成解析错误的。一开始也没多想,直接在bean中加上该参数即可,让测试的同学能顺利进行测试。
回来后,想了下,以往比较偏向使用谷歌的Gson库,但是这次这个接口解析是另外同学写的,项目中也引入了多个json解析库。jackson是Spring Boot 默认本身引入,Gson是我引入的,Fastjson是其他同学引入的。导致很多个解析不统一,序列化和反序列化容易产生不一致的结果。前不久是Fastjson解析字段顺序问题,即是 Feature.OrderedField 属性对应的功能问题。
造成上述问题的原因,是之前未能将json解析抽象成工具,有的地方没有显示使用 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 该属性,导致出现未知属性时直接抛异常了,比较尴尬。
因此下班后,整理了Gson和Jackson解析工具,后续将其统一,这样序列化和反序列化的结果相对比较统一,行为相对比较容易控制。
1、GsonUtils.java
com.google.code.gson gson 2.2.4
Gson比较简单是因为依赖比较少,直接引入即可,使用也简单。
package github.banana.utils;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import java.lang.reflect.Type;public class JsonUtils { private JsonUtils() { } private static Gson GSON; static { GSON = getGB().create(); } private static GsonBuilder getGB() { return new GsonBuilder().disableHtmlEscaping(); } public static T fromJson(String json, Class clazz) { return GSON.fromJson(json, clazz); } @SuppressWarnings("unchecked") public static T fromJson(String json, Type type) { return (T) GSON.fromJson(json, type); } public static String toJson(Object src, Type typeOfSrc) { return GSON.toJson(src, typeOfSrc); } public static String toJson(Object o) { return GSON.toJson(o); }}
2、JacksonUtils.java
com.fasterxml.jackson.core jackson-databind 2.9.8com.fasterxml.jackson.core jackson-core 2.9.8com.fasterxml.jackson.core jackson-annotations 2.9.8
jackson-annotations 包是注解属性用的,如果不需要注解属性,可以不引入。普通对象的解析,只需要引入包jackson-databind即可。
package github.banana.utils;import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.DeserializationFeature;import com.fasterxml.jackson.databind.ObjectMapper;import lombok.Data;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * Jackson json 解析工具 */public class JacksonUtils { private static ObjectMapper mapper; private JacksonUtils() { } static { mapper = new ObjectMapper(); // 反序列化遇见未知属性时不抛出异常, 默认抛出异常 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // ... 其它需要配置的均可在此配置 // 更多配置参考 https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features } /** * 普通对象序列化为字符串 * * @param o 普通对象 * @return 序列化后的字符串 * @throws Exception 序列化异常 */ public static String toJson(Object o) throws Exception { return mapper.writeValueAsString(o); } /** * 普通对象反序列化, 内部可嵌套 * * @param json 原始json字符串 * @param clazz 期待解析的目标bean对象 * @param 目标对象 * @return 解析后的泛型目标对象 * @throws Exception 解析异常, 调用捕获 */ public static T fromJson(String json, Class clazz) throws Exception { return mapper.readValue(json, clazz); } /** * 引用对象解析反序列化, 比如解析成 {@link List} {@link java.util.Map} *
*
* TypeReference ref = new TypeReference>() { * } *
* 该引用比较难构造, 可直接拷贝 * * @param json 原始json字符串, 典型如json数组 * @param ref 需要借助目标引用类型 * @param 目标对象 * @return 解析后的目标泛型对象 * @throws Exception 解析异常 */ public static T fromJson(String json, TypeReference ref) throws Exception { return mapper.readValue(json, ref); } public static void main(String[] args) throws Exception { // 1. 普通对象解析 String json = "{"name":"张三