SpringBoot + Jackson配置序列化及发序列号

文章介绍了两种方法来配置Jackson库处理Java8的LocalDate和LocalDateTime类型。方法一通过扩展SimpleModule类,添加自定义的序列化和反序列化器。方法二则是在ObjectMapper实例化时直接进行配置,并使用JavaTimeModule。两种方法都涉及到DateTimeFormatter来设定日期时间格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配置LocalDate和LocalDateTime序列化及反序列化方法

方法1:


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.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Jackson 配置
 * 直接对SimpleModule对象配置,避免其他地方的Jackson配置被覆盖的问题
 *
 * @author kou
 */
@Configuration
public class JacksonModuleConfiguration extends SimpleModule {

    public JacksonModuleConfiguration() {
        // long转为字符串
        this.addSerializer(Long.class, ToStringSerializer.instance);
        this.addSerializer(Long.TYPE, ToStringSerializer.instance);
        this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }

运行结果

方法2:


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
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.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * 日期序列化
 *
 * @author kou
 */
@Configuration
public class LocalDateTimeSerializerConfig {

    @Bean(name = "mapperObject")
    public ObjectMapper getObjectMapper() {
        ObjectMapper om = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // 序列化
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

        // 反序列化
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

        om.registerModule(javaTimeModule);
        // 或略不识别的字段
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return om;
    }

}

运行结果:

使用  ObjectMapper objectMapper = new ObjectMapper() 序列化时需指定

 // 加工后的数据,包含数据来源
        Map<String, Object> processData = new HashMap<>(8);
        processData.put("date", LocalDate.now());
        processData.put("time", LocalDateTime.now());

        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule timeModule = new JavaTimeModule();
        timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        objectMapper.registerModule(timeModule);
        String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(processData);

### 实现Spring Boot中针对Jackson序列化错误的全局异常处理 为了有效应对Jackson序列化过程中可能出现的各种问题,在Spring Boot应用里可以创建一个全局异常处理器。这不仅有助于统一管理不同类型的异常,还能提高系统的健壮性和用户体验。 #### 创建自定义异常类 首先,建议为特定于应用程序逻辑的异常情况设计专门的异常类型。对于Jackson序列化的失败情形而言,可以从`HttpMessageNotReadableException`继承或封装一个新的异常类别: ```java public class JsonDeserializationException extends RuntimeException { public JsonDeserializationException(String message, Throwable cause) { super(message, cause); } } ``` #### 编写全局异常控制器 接着利用`@ControllerAdvice`注解构建一个用于捕捉并响应HTTP请求解析期间生的任何未捕获异常的组件。在此处特别关注由Jackson的相关异常,并返回适当的消息给客户端。 ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex){ String errorMessage = "Failed to read HTTP message: " + ex.getMostSpecificCause().getMessage(); Map<String,Object> body=new HashMap<>(); body.put("timestamp",new Date()); body.put("message","Bad Request"); body.put("details",errorMessage); return new ResponseEntity<>(body,new HttpHeaders(),HttpStatus.BAD_REQUEST); } } ``` 上述代码片段展示了当遇到`HttpMessageNotReadableException`时如何构造带有状态码400(即坏请求)及描述性的错误信息作为回应的内容结构[^1]。 此外,还可以进一步细化对不同类型输入验证错误的具体反馈,例如指定哪些字段不符合预期格式等细节,从而使得API消费者更容易理解哪里出了错以及怎样修正它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值