Jackson基本使用

举报
兮动人 发表于 2022/10/24 21:03:13 2022/10/24
【摘要】 1. 序列化 1.1 只包含非 null 属性 1.1.1 全局配置 1.1.2 单个 bean 配置 1.2 日期时间格式化 1.2.1 全局配置 1.2.2 单个 bean 配置 1.3 序列化的美化输出 2. 反序列化 2.1 忽略不存在的 key 2.2 泛型的处理 3. 通用配置 3.1 驼峰转下划线和下划线转驼峰 3.2 指定属性名和JSON字符串中Key对应的关系 3.3 忽...
  • 导入Jackson所需的依赖
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.1</version>
</dependency>
<!--对localDateTime等jdk8时间日期api的转换支持-->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.10.1</version>
</dependency>
  • 可以看到 jsr310 依赖是包含 databind 依赖的
    在这里插入图片描述

1. 序列化

1.1 只包含非 null 属性

  • 默认是包含 null
@Test
public void test1() throws JsonProcessingException {
    Person person = new Person();
    person.setId(1);
//        person.setName("兮动人");
    person.setAge(20);
    person.setBirthDate(new Date());
    person.setAddress("深圳市");
    String s = objectMapper.writeValueAsString(person);
    System.out.println(s);

}

在这里插入图片描述

1.1.1 全局配置

  • 配置不包含 null,全局配置
	private static ObjectMapper objectMapper = new ObjectMapper();
	
	static {
	    /**
	     * 序列化的配置
	     */
	    // 全局配置:配置序列化时只包含非空属性
	    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
	}
	
	/**
	 * 序列化
	 */
	@Test
	public void test1() throws JsonProcessingException {
	    Person person = new Person();
	    person.setId(1);
	//        person.setName("兮动人");
	    person.setAge(20);
	    person.setBirthDate(new Date());
	    person.setAddress("深圳市");
	    String s = objectMapper.writeValueAsString(person);
	    System.out.println(s);
	
	}

在这里插入图片描述

1.1.2 单个 bean 配置

  • 单个 bean 配置指定非空
    在这里插入图片描述

1.2 日期时间格式化

@Data
public class Person {

    private Integer id;
    private String name;
    private Integer age;
    private String address;
    private boolean flag;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthDate;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime registerDate;

}
	private static ObjectMapper objectMapper = new ObjectMapper();
	
	static {
	   /**
	    * 序列化的配置
	    */
	   // 配置序列化时只包含非空属性
	   objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
	
	}
	
	/**
	* 序列化
	*/
	@Test
	public void test1() throws JsonProcessingException {
	   Person person = new Person();
	   person.setId(1);
	   person.setName("兮动人");
	   person.setAge(20);
	   person.setBirthDate(new Date());
	   person.setAddress("深圳市");
	   person.setRegisterDate(LocalDateTime.now());
	
	   String s = objectMapper.writeValueAsString(person);
	   System.out.println(s);
	
	}
  • 可以看到只有 Date birthDate 属性转换成功了,LocalDateTime registerDate 格式是没有转换的
    在这里插入图片描述

1.2.1 全局配置

  • 加上 全局配置:自动通过spi发现 Jackson 的module并注册
static {
    /**
     * 序列化的配置
     */
    // 配置序列化时只包含非空属性
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

    /**
     *  全局配置:自动通过spi发现 Jackson 的module并注册
     *
     */
    objectMapper.findAndRegisterModules();
}

在这里插入图片描述

1.2.2 单个 bean 配置

  • 手动配置
private static ObjectMapper objectMapper = new ObjectMapper();

   private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

       static {
           /**
            * 序列化的配置
            */
           // 配置序列化时只包含非空属性
           objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

           /**
            *  全局配置:自动通过spi发现 Jackson 的module并注册
            */
//            objectMapper.findAndRegisterModules();

           //手动配置 JavaTimeModule 并注册
           JavaTimeModule javaTimeModule = new JavaTimeModule();
           // 序列化
           javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
           // 反序列化
           javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
           // 注册
           objectMapper.registerModule(javaTimeModule); 

       }

在这里插入图片描述
在这里插入图片描述

  • 可以看到 LocalDateTime 类型也可以通过手动配置的方式实现格式化效果
    在这里插入图片描述

1.3 序列化的美化输出

// 序列化的美化输出
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);    

在这里插入图片描述

2. 反序列化

2.1 忽略不存在的 key

private static ObjectMapper objectMapper = new ObjectMapper();

@Test
public void test2() throws JsonProcessingException {

    String str = "{\n" +
            "  \"id\" : 1,\n" +
            "  \"name\" : \"兮动人\",\n" +
            "  \"age\" : 20,\n" +
            "  \"address\" : \"深圳市\",\n" +
            "  \"flag\" : false,\n" +
            "  \"birthDate\" : \"2022-10-09 15:29:56\",\n" +
            "  \"registerDate\" : \"2022-10-09 15:29:56\"\n" +
            "}";

    Person person = objectMapper.readValue(str, Person.class);
    System.out.println(person);
}

在这里插入图片描述

  • 如果在JSON字符串中加入个没有定义的属性,就会报错找不到这个属性
    在这里插入图片描述在这里插入图片描述

  • 设置 忽略 不存在的属性,两种写法都可以

// 设置 忽略 不存在的属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
  • 在 fastjson 中,默认就会忽略这些不存在的 key

2.2 泛型的处理

@Data
public class ResultDTO<T> {

    private Boolean success = Boolean.TRUE;

    private T data;

    private ResultDTO(){}

    public static <T> ResultDTO<T> buildSuccess(T t) {
        ResultDTO<T> result = new ResultDTO<>();
        result.setData(t);
        return result;
    }

}
  • 输出经过泛型处理的结果和泛型里的 Person 对象
/**
 * 泛型的处理
 */
@Test
public void test3() throws JsonProcessingException {
    Person person = new Person();
    person.setName("xdr");
    person.setAddress("深圳");
    ResultDTO<Person> personResultDTO = ResultDTO.buildSuccess(person);
    String s = objectMapper.writeValueAsString(personResultDTO);
    // 反序列化为 ResultDTO<Person>
    ResultDTO<Person> dataResult = objectMapper.readValue(s, new TypeReference<ResultDTO<Person>>() {
    });
    System.out.println("dataResult: " + dataResult);
    System.out.println("data: " + dataResult.getData()); // 输出里面的 Person
}

在这里插入图片描述

3. 通用配置

  • 指序列化或反序列化的时候都可以使用

3.1 驼峰转下划线和下划线转驼峰

  • 全局配置:

1、序列化:驼峰转下划线

// 驼峰转下划线 userName -> user_name
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

在这里插入图片描述

/**
 * 序列化
 */
@Test
public void test1() throws JsonProcessingException {
    Person person = new Person();
    person.setId(1);
    person.setName("兮动人");
    person.setAge(20);
    person.setBirthDate(new Date());
    person.setAddress("深圳市");
    person.setRegisterDate(LocalDateTime.now());

    String s = objectMapper.writeValueAsString(person);
    System.out.println(s);
}

在这里插入图片描述

2、反序列化:下划线转驼峰

/**
 * 反序列化
 */
@Test
public void test2() throws JsonProcessingException {

    String str = "{\n" +
            "  \"id\" : 1,\n" +
            "  \"name\" : \"兮动人\",\n" +
            "  \"age\" : 20,\n" +
            "  \"address\" : \"深圳市\",\n" +
            "  \"flag\" : false,\n" +
            "  \"birth_date\" : \"2022-10-18 20:01:32\",\n" +
            "  \"register_date\" : \"2022-10-18 20:01:32\"\n" +
            "}\n";

    Person person = objectMapper.readValue(str, Person.class);
    System.out.println(person);
}

在这里插入图片描述

3.2 指定属性名和JSON字符串中Key对应的关系

  • 指定属性名,相当于给属性别名
    在这里插入图片描述

  • 序列化输出后,就是指定的别名
    在这里插入图片描述

  • 把上面JSON字符串反序列化后,输出的就是对应的 address 属性值
    在这里插入图片描述

3.3 忽略指定属性

  • 忽略 age 属性,默认为 true
    在这里插入图片描述

  • 序列化后就没有这个值输出了
    在这里插入图片描述

  • 反序列后即便传了 age 属性,也不会进行赋值处理
    在这里插入图片描述

4. 利用 Jackson 做对象的更新

  • 对象更新:对象的合并/重写,如果后者的对象有值,则用后者的,否则前者的值不变
/**
 * 对象的更新
 */
@Test
public void test4() throws JsonMappingException {
    Person person1 = new Person();
    person1.setId(22);
    person1.setName("xdr");
    person1.setAddress("深圳 ");

    Person person2 = new Person();
    person2.setId(33);

    Person person = objectMapper.updateValue(person1, person2);
    System.out.println(person);
}

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。