自定义Jackson配置,解决LocalDateTime序列化问题
Sync All Branches to GitHub / sync (push) Successful in 3s

This commit is contained in:
hanfuye
2026-01-06 17:28:59 +08:00
parent 275e7dded9
commit 5c18560351
5 changed files with 120 additions and 26 deletions
@@ -0,0 +1,72 @@
package top.crushtj.xiaoyishu.auth.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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.deser.YearMonthDeserializer;
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 com.fasterxml.jackson.datatype.jsr310.ser.YearMonthSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.crushtj.framework.common.constant.DateConstants;
import top.crushtj.framework.common.utils.JsonUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.TimeZone;
/**
* @author ayi
* @version V1.0
* @title JacksonConfig
* @description jackson 配置类
* @date 2026/01/06
*/
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// 忽略未知属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 设置凡是为 null 的字段,返参中均不返回,请根据项目组约定是否开启
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 设置时区
objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
// JavaTimeModule 用于指定序列化和反序列化规则
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 支持 LocalDateTime、LocalDate、LocalTime
// 支持 LocalDateTime、LocalDate、LocalTime
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateConstants.DATE_FORMAT_Y_M_D_H_M_S));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateConstants.DATE_FORMAT_Y_M_D_H_M_S));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateConstants.DATE_FORMAT_Y_M_D));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateConstants.DATE_FORMAT_Y_M_D));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateConstants.DATE_FORMAT_H_M_S));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateConstants.DATE_FORMAT_H_M_S));
// 支持 YearMonth
javaTimeModule.addSerializer(YearMonth.class, new YearMonthSerializer(DateConstants.DATE_FORMAT_Y_M));
javaTimeModule.addDeserializer(YearMonth.class, new YearMonthDeserializer(DateConstants.DATE_FORMAT_Y_M));
objectMapper.registerModule(javaTimeModule);
JsonUtils.init(objectMapper);
return objectMapper;
}
}
@@ -1,5 +1,8 @@
package top.crushtj.xiaoyishu.auth.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import top.crushtj.framework.biz.operationlog.aspect.ApiOperationLog;
import top.crushtj.framework.common.response.Response;
@@ -7,8 +10,6 @@ import top.crushtj.xiaoyishu.auth.vo.User;
import java.time.LocalDateTime;
import org.springframework.web.bind.annotation.GetMapping;
/**
*
* @Title: TestController
@@ -31,4 +32,10 @@ public class TestController {
.build());
}
@PostMapping("/test2")
@ApiOperationLog(description = "测试接口2")
public Response<User> test2(@RequestBody User user) {
return Response.success(user);
}
}
@@ -1,11 +1,12 @@
package top.crushtj.xiaoyishu.auth.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;
import lombok.Data;
/**
*
@@ -17,6 +18,8 @@ import lombok.Data;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Long id;
private String name;
@@ -1,5 +1,7 @@
package top.crushtj.framework.common.constant;
import java.time.format.DateTimeFormatter;
/**
* @Title: DateConstants
* @Description: 日期常量
@@ -8,7 +10,22 @@ package top.crushtj.framework.common.constant;
*/
public interface DateConstants {
/**
* 年-月-日 时:分:秒
* DateTimeFormatter年-月-日 时:分:秒
*/
String Y_M_D_H_M_S_FORMAT = "yyyy-MM-dd HH:mm:ss";
DateTimeFormatter DATE_FORMAT_Y_M_D_H_M_S = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* DateTimeFormatter:年-月-日
*/
DateTimeFormatter DATE_FORMAT_Y_M_D = DateTimeFormatter.ofPattern("yyyy-MM-dd");
/**
* DateTimeFormatter:时:分:秒
*/
DateTimeFormatter DATE_FORMAT_H_M_S = DateTimeFormatter.ofPattern("HH:mm:ss");
/**
* DateTimeFormatter:年-月
*/
DateTimeFormatter DATE_FORMAT_Y_M = DateTimeFormatter.ofPattern("yyyy-MM");
}
@@ -1,17 +1,10 @@
package top.crushtj.framework.common.utils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.SneakyThrows;
import top.crushtj.framework.common.constant.DateConstants;
/**
*
@@ -21,24 +14,26 @@ import top.crushtj.framework.common.constant.DateConstants;
* @Date: 2025/11/21
*/
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
static {
OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// JavaTimeModule 用于指定序列化和反序列化规则
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 支持 LocalDateTime
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateConstants.Y_M_D_H_M_S_FORMAT)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateConstants.Y_M_D_H_M_S_FORMAT)));
OBJECT_MAPPER.registerModules(javaTimeModule); // 解决 LocalDateTime 的序列化问题
OBJECT_MAPPER.registerModules(new JavaTimeModule());
}
/**
* 初始化:统一使用 Spring Boot 个性化配置的 ObjectMapper
*
* @param objectMapper
*/
public static void init(ObjectMapper objectMapper) {
OBJECT_MAPPER = objectMapper;
}
/**
* 将对象转换为 JSON 字符串
*
*
* @param obj 要转换的对象
* @return JSON 字符串
*/