jackson反序列化复杂数据类型(泛型数据类型)

时间:2025-03-15 15:13:01

问题

网上很多都是普通的实体类序列化跟反序列化,而对泛型数据的反序列化却比较少,查询了很多资料都不能用,要么就是讲的太复杂,最近在工作中遇到了这个问题,记录下解决方式

资料

首先我们来参考下网上的一段代码,从这段代码中我们可以参看下集合中序列化的方式,但是没有很好的封装,如果写在实际的业务代码中会显得很繁琐,本篇文章我们是借鉴的第一种方式来解决这个问题的


public class Demo{

    public String method() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        User user = new User();
        (1);
        Pager<User> pager = new Pager<User>();
        List<User> users = new ArrayList<User>();
        (user);
        (users);
        String json = (pager);
        // 方式1
        Pager<User> userPager1 = (json, new TypeReference<Pager<User>>() {
        });
        // 方式2
        Type[] types = new Type[1];
        types[0] = ;
        final ParameterizedTypeImpl type = (, types, ());
        TypeReference typeReference = new TypeReference<Pager>() {
            @Override
            public Type getType() {
                return type;
            }
        };
        Pager<User> userPager2 = (json, typeReference);
        // 方式3
        JavaType javaType = ().constructParametrizedType(, , );
        Pager<User> userPager3 = (json, javaType);
        // 方式4
        JavaType javaType1 = ().constructParametricType(, );
        Pager<User> userPager4 = (json, javaType1);
        // 方式5,新建另一个指定具体泛型T的参数的类
        PagerAppoint userPager5 = (json, );
        // 数组泛型的序列化和反序列化
        String json1 = (users);
        JavaType javaType2 = ().constructParametricType(, );
        List<User> users1 = (json1, javaType2);
        // HashMap
        Map<String, User> map = new HashMap<String, User>(16);
        ("test", user);
        String json2 = (map);
        // 1
        Map<String, User> users2 = (json2, new TypeReference<Map<String, User>>() {
        });
        // 2
        JavaType javaType3 = ().constructParametricType(, , );
        Map<String, User> users3 = (json2, javaType3);

        return "hello world";
    }
}

实体类

创建一个包含泛型的实体类,其中data是一个泛型数据

@Data
public class BaseResponse<T> {
    /**
     * 请求ID
     */
    private String requestId;
    /**
     * Token验证码
     */
    private String queueMsg;
    /**
     * 错误编码
     */
    private String errorCode;

    /**
     * 数据
     */
    private T data;

}

再创建一个data对应的实体类

@Data
public class QuerySubmitErrorInfoResponse {
    /**
     * 机构名称
     */
    private String orgname;
    /**
     * 支付服务类别
     */
    private String bizcatgname;
    /**
     * 业务类型
     */
    private String biztypename;
    /**
     * 维度名
     */
    private String dimname;
    /**
     * 第二维度名
     */
    private String dimnames;
    /**
     * 校验信息
     */
    private String remark;

    
}

如果此时T data是一个普通的数据对象,比如QuerySubmitErrorInfoResponse这种,此时很好操作,加入是一个List<QuerySubmitErrorInfoResponse> 此时操作变的繁琐

解决

上面所说的,我用的是第一种思路来解决这个问题,需要一个TypeReference来转换,我简单的封装了一下

public <T> T jsonToObject(String responseJson, TypeReference<T> valueTypeRef) {
        try {
            return (responseJson, valueTypeRef);
        } catch (IOException e) {
            throw new JsonUtilException("Failed to convert json to object", e);
        }
    }

结束

反序列化代码块如下

BaseResponse<List<QuerySubmitErrorInfoResponse >> response = ().jsonToObject(result, new TypeReference<BaseResponse<List<QuerySubmitErrorInfoResponse >>>() {
            });

上传一个我用到的完整的工具类

package ;

import ;
import ;
import ;
import ;
import .*;
import ;

import ;
import ;

public class JsonUtil {

    private ObjectMapper mapper = new ObjectMapper();

    JsonUtil() {
        (.NON_NULL);
        (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //(PropertyNamingStrategy.SNAKE_CASE);
        (new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
        ().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object paramT, JsonGenerator paramJsonGenerator,
                                  SerializerProvider paramSerializerProvider) throws IOException {
                //设置返回null转为 空字符串""
                ("");
            }
        });
    }

    public static JsonUtil create() {
        return new JsonUtil();
    }


    public JsonUtil setDateFormat(String pattern) {
        (new SimpleDateFormat(pattern));
        return this;
    }

    public JsonUtil unwrapRootValue() {
        (DeserializationFeature.UNWRAP_ROOT_VALUE);
        return this;
    }

    public JsonUtil wrapRootValue() {
        (SerializationFeature.WRAP_ROOT_VALUE);
        return this;
    }

    public JsonUtil setFilterProvider(FilterProvider filterProvider) {
        (filterProvider);
        return this;
    }

    public JsonUtil configure(DeserializationFeature feature, boolean state) {
        (feature, state);
        return this;
    }

    public JsonUtil setPropertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) {
        (propertyNamingStrategy);
        return this;
    }

    public String objectToJson(Object obj) {
        try {
            return (obj);
        } catch (JsonProcessingException e) {
            throw new JsonUtilException("Failed to convert object to json", e);
        }
    }

    public <T> T jsonToObject(String responseJson, Class<T> clazz) {
        try {
            return (responseJson, clazz);
        } catch (IOException e) {
            throw new JsonUtilException("Failed to convert json to object", e);
        }
    }

    public <T> T jsonToObject(String responseJson, TypeReference<T> valueTypeRef) {
        try {
            return (responseJson, valueTypeRef);
        } catch (IOException e) {
            throw new JsonUtilException("Failed to convert json to object", e);
        }
    }

    public JsonNode getJsonNode(String jsonStr) {
        try {
            return (jsonStr);
        } catch (JsonProcessingException e) {
            throw new JsonUtilException("Failed to convert request to JsonNode",
                                        e);
        } catch (IOException e) {
            throw new JsonUtilException("IO exception", e);
        }
    }

}

至此,完美解决!