高复用的Jackson序列化和反序列

本篇博客使用的POM:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.12</version>
</dependency>

 

一.    首先通过ObjectMapper 设置序列化和反序列化时候的属性(非常重要!!!,能够填大多数序列化和反序列化时候的坑)

         

private static ObjectMapper objectMapper = new ObjectMapper();

static {
    //该属性设置主要是将对象的所有字段全部列入,若有特殊需求,可以进入JsonSerialize.Inclusion该枚举类查看
    objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);

    //该属性设置主要是取消将对象的时间默认转换timesstamps(时间戳)形式
    objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);

    //该属性设置主要是将忽略空bean转json错误
    objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

    //忽略在json字符串中存在,在java类中不存在字段,防止错误。
    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    //所有日期都统一为以下样式:yyyy-MM-dd HH:mm:ss,这里可以不用我的DateTimeUtil.DATE_FORMAT,手动添加
    objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.DATE_FORMAT));
}

二.    封装序列化方法

public static <T> String objToJson(T obj) {
    if (obj == null) {
        return null;
    }

    try {
        return obj instanceof String ? (String)obj : objectMapper.writeValueAsString(obj);
    } catch (Exception e) {
        log.warn("obj To json is error", e);
        return null;
    }
}

三.    封装反序列化方法

public static <T> T json2Object(String json, Class<T> clazz) {
    if (StringUtils.isEmpty(json) || clazz == null) {
        return null;
    }

    try {
        return clazz.equals(String.class) ? (T)json : objectMapper.readValue(json, clazz);
    } catch (Exception e) {
        log.warn("json To obj is error", e);
        return null;
    }
}

     在测试debug时候,该方法得到的序列化字符串格式不好看,可以使用下面的方法

四.    到这里,序列化和反序列化的方法已经封装完毕,但是上述的反序列化方法有一个问题,就是无法处理多泛型的反序列化,

         解决方案:通过TypeReference或javaType来处理多泛型问题

扫描二维码关注公众号,回复: 2804168 查看本文章
/**
 * 通过   TypeReference    处理List<User>这类多泛型问题
 * @param json
 * @param typeReference
 * @param <T>
 * @return
 */
public static <T> T json2Object(String json, TypeReference typeReference) {
    if (StringUtils.isEmpty(json) || typeReference == null) {
        return null;
    }

    try {
        return (T)(typeReference.getType().equals(String.class) ? json : objectMapper.readValue(json, typeReference));
    } catch (Exception e) {
        log.warn("json To obj is error", e);
        return null;
    }
}
/**
 * 通过jackson 的javatype 来处理多泛型的转换
 * @param json
 * @param collectionClazz
 * @param elements
 * @param <T>
 * @return
 */
public static <T> T json2Object(String json, Class<?> collectionClazz, Class<?>...elements) {
    JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClazz, elements);

    try {
        return objectMapper.readValue(json, javaType);
    } catch (Exception e) {
        log.warn("json To obj is error", e);
        return null;
    }
}

五.    至此,高复用的Jackson序列化和反序列化工具类封装完毕(我用的日志是通过lombok的注解形式,可以使用别的)

package com.mmall.util;

import com.google.common.collect.Lists;
import com.mmall.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;

import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @author Luyue
 * @date 2018/8/11 15:58
 **/
@Slf4j
public class JsonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        //对象的所有字段全部列入
        objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);

        //取消默认转换timesstamps(时间戳)形式
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);

        //忽略空bean转json错误
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

        //忽略在json字符串中存在,在java类中不存在字段,防止错误
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //所有日期都统一为以下样式:yyyy-MM-dd HH:mm:ss
        objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.DATE_FORMAT));
    }

    public static <T> String objToJson(T obj) {
        if (obj == null) {
            return null;
        }

        try {
            return obj instanceof String ? (String)obj : objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.warn("obj To json is error", e);
            return null;
        }
    }

    /**
     * 返回格式化好的json串
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> String objToJsonPretty(T obj) {
        if (obj == null) {
            return null;
        }

        try {
            return obj instanceof String ? (String)obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (Exception e) {
            log.warn("obj To json pretty is error", e);
            return null;
        }
    }

    public static <T> T json2Object(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json) || clazz == null) {
            return null;
        }

        try {
            return clazz.equals(String.class) ? (T)json : objectMapper.readValue(json, clazz);
        } catch (Exception e) {
            log.warn("json To obj is error", e);
            return null;
        }
    }

    /**
     * 通过   TypeReference    处理List<User>这类多泛型问题
     * @param json
     * @param typeReference
     * @param <T>
     * @return
     */
    public static <T> T json2Object(String json, TypeReference typeReference) {
        if (StringUtils.isEmpty(json) || typeReference == null) {
            return null;
        }

        try {
            return (T)(typeReference.getType().equals(String.class) ? json : objectMapper.readValue(json, typeReference));
        } catch (Exception e) {
            log.warn("json To obj is error", e);
            return null;
        }
    }

    /**
     * 通过jackson 的javatype 来处理多泛型的转换
     * @param json
     * @param collectionClazz
     * @param elements
     * @param <T>
     * @return
     */
    public static <T> T json2Object(String json, Class<?> collectionClazz, Class<?>...elements) {
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClazz, elements);

        try {
            return objectMapper.readValue(json, javaType);
        } catch (Exception e) {
            log.warn("json To obj is error", e);
            return null;
        }
    }

    public static void main(String[] args) {
        User user1 = new User();
        user1.setId(1);
        user1.setEmail("[email protected]");

        String json1 = objToJson(user1);
        String json2 = objToJsonPretty(user1);

        log.info("json1 is {}", json1);
        log.info("json2 is {}", json2);

        User user = json2Object(json1, User.class);
        System.out.println("===============================");

        List<User> userList = Lists.newArrayList();
        User u1 = new User();
        u1.setId(5);
        u1.setEmail("[email protected]");

        User u2 = new User();
        u2.setId(6);
        u2.setEmail("[email protected]");

        userList.add(u1);
        userList.add(u2);
        String listJson = objToJsonPretty(userList);
        log.info("jsonList is {}", listJson);

        List<User> testUserList = json2Object(listJson, List.class);

        List<User> jsonToObj = json2Object(listJson, new TypeReference<List<User>>(){});
        List<User> jsonToObj2 = json2Object(listJson, List.class, User.class);
        System.out.println("**************************");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37585236/article/details/81590323