【问题标题】:Deserialize Date object with Jackson in Spring boot在 Spring Boot 中使用 Jackson 反序列化 Date 对象
【发布时间】: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,只加载我们需要的

标签: spring-boot jackson deserialization


【解决方案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 我只是添加了一个全局解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-03-31
    • 2018-11-17
    • 2018-01-24
    • 2014-03-11
    • 1970-01-01
    • 2020-08-07
    • 2019-04-03
    • 1970-01-01
    相关资源
    最近更新 更多