当前位置: 首页 > article >正文

【Java】Jackson序列化案例分析

1.Jackson介绍

Jackson 是一个流行的 Java 库,用于处理 JSON 数据。它提供了高效的序列化和反序列化功能,能够将 Java 对象转换为 JSON 格式,反之亦然。
它由 FasterXML 开发和维护。Jackson 的设计目标是提供高效、灵活且易于使用的 JSON 处理功能。它广泛应用于各种 Java 项目和框架中,成为处理 JSON 的事实标准之一。

  • 序列化是将 Java 对象转换为 JSON 字符串的过程。在 Jackson 中,这个过程通常由 ObjectMapper 类来完成。ObjectMapper 是 Jackson 的核心类,提供了许多方法来进行序列化操作。
  • 反序列化是将 JSON 字符串转换为 Java 对象的过程。在 Jackson 中,这个过程同样由 ObjectMapper 类来完成。

本文主要介绍Jaskson的序列化(writeValueAsString),涉及时间格式的自定义序列化

2.案例

尝试
Bean类,设置不同的数据类型。

import lombok.Data; // get/set方法
import java.time.LocalDateTime;
import java.util.Date;

@Data 
public class UserBean {

    private String name;

    private Integer age;
    
    private Date birthday;

    private LocalDateTime createTime;

    private Boolean isDelete;
}

测试类:测试Jackson的序列化功能,即将Java对象转为Json字符串

public class TestJackson {
    
   public static UserBean getBean(){
        UserBean userBean = new UserBean();
        userBean.setName("zhi");
        userBean.setAge(18);
        userBean.setBirthday(new Date());
        userBean.setCreateTime(LocalDateTime.now());
        userBean.setIsDelete(false);
        return userBean;
    }

    public static void main(String[] args) {
        UserBean user = getBean();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String userJsonStr = objectMapper.writeValueAsString(user);
            System.out.println(userJsonStr);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

输出:

{"name":"zhi","age":18,"birthday":1735125463752,"createTime":{"dayOfWeek":"WEDNESDAY","dayOfYear":360,"year":2024,"month":"DECEMBER","nano":784000000,"monthValue":12,"dayOfMonth":25,"hour":19,"minute":17,"second":43,"chronology":{"calendarType":"iso8601","id":"ISO"}},"isDelete":false}

发现时间格式可读性差,想转换为2024-12-25 19:04:19类型。

修改:在实体类中添加注解

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Data
public class UserBean {

    private String name;

    private Integer age;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthday;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;

    private Boolean isDelete;
}

再次运行并输出

{"name":"zhi","age":18,"birthday":"2024-12-25 19:22:12","createTime":{"dayOfWeek":"WEDNESDAY","dayOfYear":360,"year":2024,"month":"DECEMBER","nano":851000000,"monthValue":12,"dayOfMonth":25,"hour":19,"minute":22,"second":12,"chronology":{"calendarType":"iso8601","id":"ISO"}},"isDelete":false}

发现birthday对了,但createTime不行。

继续修改

创建自定义LocalDateTime的序列化器:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
/**
 * 自定义LocalDateTime的序列化器
 * 该序列化器用于将LocalDateTime对象转换为符合特定格式的JSON字符串
 */
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    // 定义日期时间格式器,用于将LocalDateTime格式化为字符串
    // 格式为:年-月-日 时:分:秒 时区,时区为GMT+8
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT+8"));

    /**
     * 序列化LocalDateTime对象
     *
     * @param localDateTime 待序列化的LocalDateTime对象
     * @param jsonGenerator 用于生成JSON数据的工具
     * @param serializerProvider 提供序列化器的工具,通常未使用
     * @throws IOException 当JSON生成过程中发生错误时抛出
     */
    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 将LocalDateTime转换为带有GMT+8时区的ZonedDateTime对象
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("GMT+8"));
        // 使用定义好的格式器将ZonedDateTime格式化为字符串,并写入JSON
        jsonGenerator.writeString(zonedDateTime.format(formatter));
    }
}

在实体类中添加注解@JsonSerialize(using = XXX.class)

@Data
public class UserBean {

    private String name;

    private Integer age;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthday;

    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime createTime;

    private Boolean isDelete;
}

在此运行测试方法

{"name":"zhi","age":18,"birthday":"2024-12-25 19:31:20","createTime":"2024-12-25 19:31:20","isDelete":false}

成功!

不用注解的实现

两个序列化器

public class DateSerializer extends JsonSerializer<Date> {

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT+8"));

    @Override
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 将Date对象转换为ZonedDateTime对象
        ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.of("GMT+8"));
        // 将ZonedDateTime对象格式化为字符串
        String formattedDate = formatter.format(zonedDateTime);
        // 将格式化后的日期时间字符串写入JSON生成器
        jsonGenerator.writeString(formattedDate);
    }
}

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    // 定义日期时间格式器,用于将LocalDateTime格式化为字符串
    // 格式为:年-月-日 时:分:秒 时区,时区为GMT+8
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT+8"));

    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 将LocalDateTime转换为带有GMT+8时区的ZonedDateTime对象
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("GMT+8"));
        // 使用定义好的格式器将ZonedDateTime格式化为字符串,并写入JSON
        jsonGenerator.writeString(zonedDateTime.format(formatter));
    }
}

实体类

 */
@Data
public class UserBean {

    private String name;

    private Integer age;

    private Date birthday;

    private LocalDateTime createTime;

    private Boolean isDelete;
}

测试方法

public class TestJackson {

   public static UserBean getBean(){
        UserBean userBean = new UserBean();
        userBean.setName("zhi");
        userBean.setAge(18);
        userBean.setBirthday(new Date());
        userBean.setCreateTime(LocalDateTime.now());
        userBean.setIsDelete(false);
        return userBean;
    }

    public static void main(String[] args) {
        UserBean user = getBean();
        ObjectMapper objectMapper = new ObjectMapper();
        // 配置ObjectMapper以处理LocalDateTime、Date类型的序列化
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        javaTimeModule.addSerializer(Date.class, new DateSerializer());
        objectMapper.registerModule(javaTimeModule);
        try {
            String userJsonStr = objectMapper.writeValueAsString(user);
            System.out.println(userJsonStr);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

输出:
在这里插入图片描述
成功!


http://www.kler.cn/a/452463.html

相关文章:

  • Redis生产实践中相关疑问记录
  • 【ollama安装】国内 ubuntu22.04 linux 环境安装ollama教程
  • 学习数量关系
  • 深度学习中的并行策略概述:1 单GPU优化
  • Python调用R语言中的程序包来执行回归树、随机森林、条件推断树和条件推断森林算法
  • NPM老是无法install,timeout?npm install失败
  • Mysql-索引的数据结构
  • 肿瘤电场仪疗法原理:科技之光,照亮抗癌之路
  • UniApp作为前端开发框架,基于Vue.js 的 AI 教学类App开发方案
  • python的OS模块和shutil模块使用
  • C# 第二阶段 modbus
  • 浏览器点击视频裁剪当前帧,然后粘贴到页面
  • Python实现机器学习驱动的智能医疗预测模型系统的示例代码框架
  • 使用sql实现将一张表的某些字段数据存到另一种表里
  • 单片机:实现SYN6288语音播报(附带源码)
  • sql之全文索引
  • Android Jetpack LiveData源码解析
  • Leetcode3218. 切蛋糕的最小总开销 I
  • WordPress Tutor LMS插件 SQL注入漏洞复现(CVE-2024-10400)
  • workman服务端开发模式-应用开发-后端api登录之浏览器版本工具开发