JacksonObjectMapper的作用
JacksonObjectMapper
的作用是在处理 JSON 数据时提供自定义的行为和配置。通过继承 ObjectMapper
类并进行一系列配置,JacksonObjectMapper
可以满足特定的应用需求,如处理特定的数据类型、格式化日期和时间、忽略未知属性等。下面详细解释 JacksonObjectMapper
的主要作用和应用场景。
主要作用
-
处理未知属性:
- 配置:
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- 作用:在反序列化 JSON 数据时,如果遇到未知属性(即 JSON 中存在但在目标对象中没有对应的字段),不会抛出异常,而是忽略这些未知属性。
- 配置:
-
自定义序列化和反序列化:
- 日期和时间格式:
- 配置:使用
LocalDateTimeDeserializer
、LocalDateDeserializer
、LocalTimeDeserializer
和LocalDateTimeSerializer
、LocalDateSerializer
、LocalTimeSerializer
。 - 作用:确保
LocalDateTime
、LocalDate
和LocalTime
类型的数据在序列化和反序列化时使用指定的格式(如yyyy-MM-dd HH:mm:ss
)。
- 配置:使用
- 大整数和长整数处理:
- 配置:使用
ToStringSerializer
。 - 作用:将
BigInteger
和Long
类型的数据在序列化时转换为字符串,避免精度丢失问题。
- 配置:使用
- 日期和时间格式:
-
提高数据处理的灵活性和准确性:
- 自定义模块:通过
SimpleModule
添加自定义的序列化器和反序列化器。 - 作用:可以根据应用的具体需求,灵活地处理各种数据类型和格式。
- 自定义模块:通过
应用场景
-
API 开发:
- 在开发 RESTful API 时,经常需要处理复杂的 JSON 数据。使用
JacksonObjectMapper
可以确保数据在传输过程中保持正确的格式和类型。 - 示例:处理日期和时间字段,确保客户端和服务器之间的时间格式一致。
- 在开发 RESTful API 时,经常需要处理复杂的 JSON 数据。使用
-
数据交换:
- 在不同系统之间进行数据交换时,可能需要处理不同类型的数据。使用
JacksonObjectMapper
可以确保数据在序列化和反序列化过程中不会丢失精度或格式。 - 示例:处理大整数(如订单编号)时,避免因数值过大而导致的精度丢失。
- 在不同系统之间进行数据交换时,可能需要处理不同类型的数据。使用
-
日志记录:
- 在记录日志时,可能需要将对象转换为 JSON 格式。使用
JacksonObjectMapper
可以确保日志中的数据格式正确,便于后续分析。 - 示例:记录用户的操作日志,确保时间戳格式统一。
- 在记录日志时,可能需要将对象转换为 JSON 格式。使用
-
数据持久化:
- 在将对象持久化到数据库或文件系统时,可能需要将对象转换为 JSON 格式。使用
JacksonObjectMapper
可以确保数据在持久化过程中保持正确的格式。 - 示例:将用户信息持久化到数据库时,确保日期和时间字段的格式正确。
- 在将对象持久化到数据库或文件系统时,可能需要将对象转换为 JSON 格式。使用
示例代码
假设我们有一个 User
类,其中包含 LocalDateTime
和 BigInteger
类型的字段。我们可以使用 JacksonObjectMapper
来处理这些字段。
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();// 收到未知属性时不报异常this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(BigInteger.class, ToStringSerializer.instance).addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));// 注册功能模块,例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}// User 类
class User {private String name;private BigInteger userId;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createdAt;@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate birthDate;@JsonFormat(pattern = "HH:mm:ss")private LocalTime loginTime;// Getters and Setters// ...
}// 测试代码
public class Main {public static void main(String[] args) throws Exception {User user = new User();user.setName("张三");user.setUserId(new BigInteger("12345678901234567890"));user.setCreatedAt(LocalDateTime.now());user.setBirthDate(LocalDate.now());user.setLoginTime(LocalTime.now());JacksonObjectMapper mapper = new JacksonObjectMapper();String json = mapper.writeValueAsString(user);System.out.println(json);User deserializedUser = mapper.readValue(json, User.class);System.out.println(deserializedUser);}
}
详细解释
-
JacksonObjectMapper
类:- 继承自
ObjectMapper
类。 - 在构造函数中进行了一系列配置,包括处理未知属性、自定义序列化和反序列化器。
- 继承自
-
User
类:- 包含
String
、BigInteger
、LocalDateTime
、LocalDate
和LocalTime
类型的字段。 - 使用
@JsonFormat
注解指定字段的格式。
- 包含
-
测试代码:
- 创建一个
User
对象并设置其属性。 - 使用
JacksonObjectMapper
将User
对象序列化为 JSON 字符串。 - 再将 JSON 字符串反序列化为
User
对象。 - 输出序列化后的 JSON 字符串和反序列化后的
User
对象。
- 创建一个
通过这些配置和测试代码,可以看到 JacksonObjectMapper
如何处理特定的数据类型和格式,确保数据在序列化和反序列化过程中保持正确的格式和类型。
**## `**this.registerModule(simpleModule)**`;详细解释这段代码
SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(BigInteger.class, ToStringSerializer.instance).addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));这段代码的作用**
这段代码的作用是创建一个 SimpleModule
对象,并在这个模块中注册多个自定义的序列化器和反序列化器。这些序列化器和反序列化器用于处理特定的数据类型,确保在序列化和反序列化过程中数据的格式和类型符合预期。下面详细解释这段代码的每一部分及其作用。
代码详解
SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(BigInteger.class, ToStringSerializer.instance).addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
逐行解释
-
创建
SimpleModule
对象:SimpleModule simpleModule = new SimpleModule();
SimpleModule
:SimpleModule
是 Jackson 提供的一个简单的模块类,用于注册自定义的序列化器和反序列化器。new SimpleModule()
:创建一个新的SimpleModule
实例。
-
添加反序列化器:
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
addDeserializer
:方法用于添加自定义的反序列化器。LocalDateTime.class
:为LocalDateTime
类型添加反序列化器,使用LocalDateTimeDeserializer
并指定日期时间格式。LocalDate.class
:为LocalDate
类型添加反序列化器,使用LocalDateDeserializer
并指定日期格式。LocalTime.class
:为LocalTime
类型添加反序列化器,使用LocalTimeDeserializer
并指定时间格式。
DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)
:创建一个日期时间格式化器,使用指定的格式字符串。
-
添加序列化器:
.addSerializer(BigInteger.class, ToStringSerializer.instance) .addSerializer(Long.class, ToStringSerializer.instance) .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
addSerializer
:方法用于添加自定义的序列化器。BigInteger.class
:为BigInteger
类型添加序列化器,使用ToStringSerializer
将BigInteger
转换为字符串。Long.class
:为Long
类型添加序列化器,使用ToStringSerializer
将Long
转换为字符串。LocalDateTime.class
:为LocalDateTime
类型添加序列化器,使用LocalDateTimeSerializer
并指定日期时间格式。LocalDate.class
:为LocalDate
类型添加序列化器,使用LocalDateSerializer
并指定日期格式。LocalTime.class
:为LocalTime
类型添加序列化器,使用LocalTimeSerializer
并指定时间格式。
具体作用
-
自定义序列化:
BigInteger
和Long
类型:使用ToStringSerializer
将这些类型的数据转换为字符串,避免在 JSON 中出现科学记数法或精度丢失。LocalDateTime
、LocalDate
和LocalTime
类型:使用自定义的序列化器将这些类型的数据转换为指定格式的字符串。
-
自定义反序列化:
LocalDateTime
、LocalDate
和LocalTime
类型:使用自定义的反序列化器将 JSON 中的字符串转换为相应的LocalDateTime
、LocalDate
和LocalTime
对象。
示例代码
假设我们有一个 User
类,其中包含 LocalDateTime
和 BigInteger
类型的字段。我们可以使用 JacksonObjectMapper
来处理这些字段。
User
类定义
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;public class User {private String name;private BigInteger userId;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createdAt;@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate birthDate;@JsonFormat(pattern = "HH:mm:ss")private LocalTime loginTime;// Getters and Setterspublic String getName() {return name;}public void setName(String name) {this.name = name;}public BigInteger getUserId() {return userId;}public void setUserId(BigInteger userId) {this.userId = userId;}public LocalDateTime getCreatedAt() {return createdAt;}public void setCreatedAt(LocalDateTime createdAt) {this.createdAt = createdAt;}public LocalDate getBirthDate() {return birthDate;}public void setBirthDate(LocalDate birthDate) {this.birthDate = birthDate;}public LocalTime getLoginTime() {return loginTime;}public void setLoginTime(LocalTime loginTime) {this.loginTime = loginTime;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", userId=" + userId +", createdAt=" + createdAt +", birthDate=" + birthDate +", loginTime=" + loginTime +'}';}
}
序列化和反序列化代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();// 收到未知属性时不报异常this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(BigInteger.class, ToStringSerializer.instance).addSerializer(Long.class, ToStringSerializer.instance).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));// 注册功能模块,例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}public class Main {public static void main(String[] args) throws Exception {// 创建一个 User 对象User user = new User();user.setName("张三");user.setUserId(new BigInteger("12345678901234567890"));user.setCreatedAt(LocalDateTime.now());user.setBirthDate(LocalDate.now());user.setLoginTime(LocalTime.now());// 创建 JacksonObjectMapper 实例JacksonObjectMapper mapper = new JacksonObjectMapper();// 序列化 User 对象为 JSON 字符串String json = mapper.writeValueAsString(user);System.out.println("序列化后的 JSON 字符串: " + json);// 反序列化 JSON 字符串为 User 对象User deserializedUser = mapper.readValue(json, User.class);System.out.println("反序列化后的 User 对象: " + deserializedUser);}
}
详细解释
-
User
类:- 包含
String
、BigInteger
、LocalDateTime
、LocalDate
和LocalTime
类型的字段。 - 使用
@JsonFormat
注解指定字段的格式。
- 包含
-
JacksonObjectMapper
类:- 继承自
ObjectMapper
类。 - 在构造函数中进行了一系列配置,包括处理未知属性、自定义序列化和反序列化器。
- 继承自
-
测试代码:
- 创建一个
User
对象并设置其属性。 - 使用
JacksonObjectMapper
将User
对象序列化为 JSON 字符串。 - 再将 JSON 字符串反序列化为
User
对象。 - 输出序列化后的 JSON 字符串和反序列化后的
User
对象。
- 创建一个
通过这些代码,可以看到 SimpleModule
如何帮助我们在序列化和反序列化过程中处理特定的数据类型和格式,确保数据的一致性和正确性。