在 Spring Boot 中使用 Jackson 反序列化 Date 对象

Posted

技术标签:

【中文标题】在 Spring Boot 中使用 Jackson 反序列化 Date 对象【英文标题】:Deserialize Date object with Jackson in Spring boot 【发布时间】:2021-02-18 14:45:30 【问题描述】:

我的数据对象返回数据为1604571544010,我需要一些更易读的东西。

我尝试了很多东西,似乎没有任何效果,我怀疑Jackson或spring版本有问题。

我尝试在application.properties

中设置数据格式

我还尝试了baeldung的所有全局配置

Pom.xml

<jackson.version>2.11.3</jackson.version>
<jackson.databind.version>2.11.3</jackson.databind.version>
<jackson.mapper.version>1.9.13</jackson.mapper.version>
<spring.boot.version>2.1.17.RELEASE</spring.boot.version>
<spring.version>5.1.18.RELEASE</spring.version>

网络配置

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder()

    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    return new Jackson2ObjectMapperBuilder().indentOutput(true).dateFormat(sdf);

DTO

@JsonProperty
public Date getStartDateTime()

    return startDateTime;

【问题讨论】:

在某种程度上,以 EpochMilli 的形式返回在被 javascript 使用时实际上很有用。因为您可以通过 new Date(EpochMilli) 直接创建 JS 日期对象。通常我建议使用它来防止时区混淆。 启动spring boot 2,日期根据ISO 8601格式化。你通常不需要指定所有版本的依赖,只需要spring-boot-starter-parent @Chayne P.S. 我知道你的意思,但我的数据模型很大,而且我最不想做的事情是逐个更新属性 @ggr 我们不会加载所有 spring-boot-starter-parent,只加载我们需要的 【参考方案1】:

您可以在 application.properties 中添加属性spring.jackson.date-format 以提供java.util.Date 的特定日期格式。

例如。 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

来源:Spring-Boot application.properties

【讨论】:

啊,我的错...您是否尝试启用 Spring 调试日志以检查您尝试的配置为何不起作用?【参考方案2】:

唯一对我有用的全局设置是 ObjectMapper

   @Bean
        @Primary
        public ObjectMapper objectMapper()
        
            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            final ObjectMapper mapper = new ObjectMapper();
            mapper.setDateFormat(sdf);
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            return mapper;
        

【讨论】:

【参考方案3】:

使用@JsonComponent。任何Date 类型都将使用此自定义序列化程序进行序列化。

@JsonComponent
class DateSerializer extends JsonSerializer<Date> 

    public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

    public DateSerializer() 
        this(null);
    

    public DateSerializer(Class<Date> t) 
        super(t);
    

    @Override
    public void serialize(
        Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException 


        jgen.writeString(sdf.format(value));

    

不使用@JsonComponent

WebConfiguration注册自定义序列化器。

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter 

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) 
        SimpleModule m = new SimpleModule();
        m.addSerializer(Date.class, new DateSerializer());
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().modules(m);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    

或者如果确实想标记每个字段

@JsonSerialize(using = DateSerializer.class)
public Date getStartDateTime()
    
        return startDateTime;
    

【讨论】:

我确信这会起作用,但我需要一个全局解决方案,我不必检查每个日期属性 @MariaFinkelstein 我只是添加了一个全局解决方案。

以上是关于在 Spring Boot 中使用 Jackson 反序列化 Date 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 中使用 Jackson 反序列化 Date 对象

Jackson 在我的 Spring Boot 应用程序中忽略了 spring.jackson.properties

Spring boot 拾遗 —— Spring Cache 使用 Jackson 与 自定义 TTL

在 Jackson / Spring Boot 中测试自定义 Json Deserializer

Spring boot与Jackson ObjectMapper

在 Spring Boot 应用程序中配置 Jackson mixin