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类,设置不同的数据类型。
java">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字符串
java">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")
java">@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的序列化器:
java">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+8private 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生成过程中发生错误时抛出*/@Overridepublic void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {// 将LocalDateTime转换为带有GMT+8时区的ZonedDateTime对象ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("GMT+8"));// 使用定义好的格式器将ZonedDateTime格式化为字符串,并写入JSONjsonGenerator.writeString(zonedDateTime.format(formatter));}
}
在实体类中添加注解@JsonSerialize(using = XXX.class)
java">@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}
成功!
不用注解的实现
两个序列化器
java">public class DateSerializer extends JsonSerializer<Date> {private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT+8"));@Overridepublic 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+8private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT+8"));@Overridepublic void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {// 将LocalDateTime转换为带有GMT+8时区的ZonedDateTime对象ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("GMT+8"));// 使用定义好的格式器将ZonedDateTime格式化为字符串,并写入JSONjsonGenerator.writeString(zonedDateTime.format(formatter));}
}
实体类
java"> */
@Data
public class UserBean {private String name;private Integer age;private Date birthday;private LocalDateTime createTime;private Boolean isDelete;
}
测试方法
java">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);}}
}
输出:
成功!