JackSon

2023-11-07

前后端分离开发中常用到的数据交互方式就是json。本文主要讲解对jackson对json的相关操作。

jackson

基础篇

1、引入依赖:

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

2、、创建ObjectMapper常用配置

private static final ObjectMapper objectMapper; 
static { 
objectMapper = new ObjectMapper(); // 对象的所有字段全部列入,还是其他的选项,可以忽略null等 
objectMapper.setSerializationInclusion(Include.ALWAYS); // 设置Date类型的序列化及反序列化格式
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 忽略空Bean转json的错误 
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // 忽略未知属性,防止json字符串中存在,而java对象中不存在对应属性的情况出现错误 
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 注册一个时间序列化及反序列化的处理模块,用于解决jdk8中localDateTime等的序列化问题 
objectMapper.registerModule(new JavaTimeModule());}

本文中用到的测试类,后续测试均使用本类

public class JsonUser { 
private String userName; 
private String pwd; private String address;
private List<String> user_phone; 
private JsonPet pet;  //基础篇还用不到,解决对象内嵌套问题
//省略构造器、get()、set()、toString() 
}
public class JsonPet {
 private String name;
 private String age; 
    //省略构造器、get()、set()、toString()列 
}

3、对象转json字符串

JsonUser user = new JsonUser("张三", "1246", "北京市海淀区", Collections.singletonList("15838609251")); //对象转json字符串 String s = objectMapper.writeValueAsString(user); System.out.println(s);

输出:

{“userName”:“张三”,“pwd”:“1246”,“address”:“北京市海淀区”,“user_phone”:“15838609251”}

注1:对象转json需要属性拥有get方法。这种方式是通过get方法来获取对象属性的,少几个get方法,输出的字符串就少几个属性。

注2:注:对象中的Map、List属性,转换的时候,会默认转换(不需要额外的配置)。

4、json字符串转对象

String str = "{\"userName\":\"张三\",\"pwd\":\"1246\",\"address\":\"北京市海淀区\",\"user_phone\":[\"15838609251\"]}"; JsonUser jsonUser = objectMapper.readValue(str, JsonUser.class);

基础篇到这里就结束了。想来,我们的小伙伴肯定有很多疑问,使用中肯定会遇到各种问题,下面的高级篇将进行详细讲解。

高级篇

问题1: 假设反序列化的json里面有个字段,在POJO类中没有,会反序列失败。

基础篇中的测试实体类JsonUser里面有一个字段pet,这也是一个实体类。

如果直接执行如下代码:

String str = "{\"userName\":\"张三\",\"pwd\":\"1246\",\"address\":\"北京市海淀区\",\"user_phone\":[\"15838609251\"],\"pet\":{\"name\":\"Jack\",\"age\":\"12\"}}";
JsonUser jsonUser = objectMapper.readValue(str,JsonUser.class);

会报错。

解决办法①:

修改JsonPet的有参构造方法

public class JsonPet { 
    private int age; 
    private String name; 
    @JsonCreator public 
    Person(@JsonProperty("age") int age, @JsonProperty("name") String name) { 
        this.age = age; this.name = name; 
    } 
}

解决办法②:

自创建一个反序列化的方法

public class JsonPet { 
    private String name; 
    private String age; 
    public JsonPet() { } 
    public JsonPet(String name, String age) { this.name = name; this.age = age; } 
    /** * 反序列化时需要用的,支持Documentation:""的场景。 * 注:使用这种方式一定要有无参构造 */ 
    @JsonCreator public static JsonPet create(String str) throws IOException { 
        //这个地方是对""进行处理 
        if (StringUtils.isBlank(str)) { return null; }
        // 这里其实就是将value单独抽出来,再次进行反序列化; 
        return (new ObjectMapper()).readValue(str, JsonPet.class); 
    } 
}

说明:

  1. 在反序列化时,Jackson默认会调用对象的无参构造函数,如果我们不定义任何构造函数,JVM会负责生成默认的无参构造函数。但是如果我们定义了构造函数,并且没有提供无参构造函数时,Jackson会报错;
  2. @JsonCreator 该注解用在对象的反序列时指定特定的构造函数或者工厂方法。如果默认构造函数无法满足需求,或者说我们需要在构造对象时做一些特殊逻辑,可以使用该注解。
  3. 如果是构造函数,则需要配合@JsonProperty来使用。

问题2: 假设反序列化的json里面有个字段,在POJO类中是泛型,如何处理。

解决办法:

借助于TypeReference类来处理。

JsonUser jsonUser = objectMapper.readValue(str, new TypeReference<Woman<Dog>>() {});

关于TypeReference的用法可自行百度。

问题3: 假设反序列化的json里面有个字段名,和在POJO类中的字段名,不一致。

解决:在这个字段名前加注解 @JsonProperty。

注解很多,这里就不列举了,可自行百度。

!!!这里说一个小技巧!!!

找到jackson的注解包: com.fasterxml.jackson.annotation

在这里插入图片描述

在这个注解包下面,就是jackson的注解啦,感兴趣的小伙伴可以看一下。可以百度都搜一下感兴趣的。

最后的最后,送上干货,jackson在开发中使用的工具类

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JackSon 的相关文章

随机推荐