Jackson序列化与反序列化

 

一、简介

Jackson的两个版本是不同包名
1.x的包名是org.codehaus.jackson,2.x的包名com.fasterxml.jackson
1.x版本现在只提供bug-fix,2.x版本还在不断开发和发布中。新项目建议直接用2x,即fasterxml jackson

Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高。

官方文档

二、使用

引入jar包

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.6</version>
</dependency>

常用注解

//类上使用,属性为NULL则不参与JSON序列化
@JsonInclude(JsonInclude.Include.NON_NULL)

//在json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。
//一般标记在属性或者方法上,返回的json数据不包含该属性。
@JsonIgnore

更多查看官方注解文档

对象转Json

public static <T> String obj2String(T obj) {
    if (obj == null) {
        return null;
    }
    try {
        return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
        // 带格式
        // return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

Json转对象

public static <T> T string2Obj(String str, Class<T> clazz) {
    if (str == null || str.length() == 0 || clazz == null) {
        return null;
    }
    try {
        return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

测试

public static void main(String[] args) {
    User user1 = new User();
    user1.setId(1);
    user1.setEmail("aasdas@asdas.com");
    user1.setCreateTime(new Date());

    String s = JsonUtil2.obj2String(user1);
    System.out.println(s);

    User users = JsonUtil2.string2Obj(s, User.class);
    System.out.println(users.getEmail());
}

img

换一个类再测试下

public static void main(String[] args) {
User user1 = new User();
    user1.setId(1);
    user1.setEmail("aasdas@asdas.com");
    user1.setCreateTime(new Date());
    User user2 = new User();
    user2.setId(2);
    user2.setEmail("vbnhng@jyugj.com");
    List<User> userList = new ArrayList<>();
    userList.add(user1);
    userList.add(user2);

    String userListStr = JsonUtil2.obj2StringPretty(userList);
    System.out.println(userListStr);

    List<User> userss = JsonUtil2.string2Obj(userListStr, List.class);
    System.out.println(userss.get(0).getCreateTime());
}

img

可以看到在反序列化后使用时报错了,Debug查看下

img

可以看到List集合里面并不是我们预想的User类型,而是LinkedHashMap类型,这是因为泛型的运行时擦除,对于局部变量来说, 泛型信息是无法获取的

Json转对象树

public static <T> T string2Obj(String str, TypeReference<T> typeReference) {
    if (str == null || str.length() == 0 || typeReference == null) {
        return null;
    }
    try {
        return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

img

附上Demo