You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Reactive全局日期配置失效 JSON序列化仍返回时间戳

Spring Reactive 全局Date序列化不生效问题解决方案

问题根因

Spring 响应式栈(WebFlux)和传统Spring MVC的序列化组件加载逻辑存在差异:

  • 传统Spring MVC使用MappingJackson2HttpMessageConverter做JSON序列化,会默认读取spring.jackson.*前缀的配置绑定到全局ObjectMapper
  • WebFlux使用Jackson2JsonEncoder做序列化,当通过RouterFunction定义接口、调用bodyValue()输出响应时,如果没有显式给编解码器指定自定义的ObjectMapper,框架会初始化独立的默认ObjectMapper实例,该实例默认开启WRITE_DATES_AS_TIMESTAMPS特性,不会读取application.properties中的Jackson配置,也不会使用JacksonAutoConfiguration预配置的ObjectMapper Bean,因此全局配置不生效。

已尝试方案无效原因

  • 引入com.fasterxml.jackson.datatype:jackson-datatype-joda依赖无作用:该依赖仅用于序列化Joda Time的日期类型,不处理JDK原生java.util.Date的序列化逻辑
  • spring.jackson.serialization.write-dates-as-timestamps=false配置未被WebFlux序列化组件加载,仅对Spring上下文持有的ObjectMapper生效,没有传递到实际执行序列化的Jackson2JsonEncoder中
  • 逐字段添加@JsonFormat生效是因为注解优先级高于序列化器默认配置,但无法解决全局统一配置的需求;全量替换Date为LocalDateTime需要大量重构,成本较高。

正确全局配置方案

无需修改现有实体类、无需逐字段加注解、无需替换Date类型,两步即可实现全局格式化:

  1. 移除不必要的jackson-datatype-joda依赖(无实际作用)
  2. 添加WebFlux配置类,自定义全局ObjectMapper并绑定到WebFlux编解码器:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

@Configuration
public class GlobalWebFluxConfig implements WebFluxConfigurer {

    @Bean
    public ObjectMapper customObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 关闭日期序列化为时间戳的配置
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 配置Date类型全局序列化格式
        SimpleModule dateModule = new SimpleModule();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 指定东八区时区,避免时间偏差
        dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        dateModule.addSerializer(Date.class, new DateSerializer(false, dateFormat));
        objectMapper.registerModule(dateModule);
        return objectMapper;
    }

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        ObjectMapper objectMapper = customObjectMapper();
        // 将自定义ObjectMapper注入WebFlux的JSON编解码器,保证序列化时使用自定义配置
        configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper));
        configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper));
    }
}

配置完成后重启应用,所有接口返回的Date类型、Optional<Date>类型字段都会统一序列化为yyyy-MM-dd HH:mm:ss格式,不会再返回时间戳。

提示:如果项目中已有其他ObjectMapper自定义配置,直接注入现有ObjectMapper实例补充日期序列化规则即可,不要重复创建ObjectMapper Bean避免覆盖原有配置。

内容的提问来源于stack exchange,提问作者Tom Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:06:23