Spring Boot,在 REST 响应中将日期时间精度定义为毫秒

Posted

技术标签:

【中文标题】Spring Boot,在 REST 响应中将日期时间精度定义为毫秒【英文标题】:Spring Boot, define datetime precision to millis in REST response 【发布时间】:2020-01-30 15:16:57 【问题描述】:

我创建了一个提供 REST API 的 Spring Web 应用程序。我正在使用 Spring Boot 2.x、Spring Data REST、Spring HATEOAS、Spring JPA、Hibernate 5.3、mysql

我也在使用 jackson-datatype-jsr310。

我在整个应用程序中使用 UTC 日期,并将 UTC 日期存储在 Mysql 中。

在我的bean中日期定义为:

    @NotNull
    @Column(nullable = false)
    private Instant validUntil;

一切正常,但是当 API 被使用时,日期会以这种格式返回:

"validUntil" : "2019-11-05T22:59:59.999999Z"

我想将我的应用程序中的每个日期时间截断为毫秒,所以日期应该是:

“validUntil”:“2019-11-05T22:59:59.999Z”

在我的 @Configuration 中,我使用的是自定义 JacksonModule:

    @Bean
    public Module customJacksonModule() 
        SimpleModule customJacksonModule = new SimpleModule();
        customJacksonModule.addSerializer(ConstraintViolationException.class, constraintViolationExceptionSerializer());
        customJacksonModule.addSerializer(ValidationException.class, validationExceptionSerializer());
        customJacksonModule.addSerializer(cloud.optix.server.exceptions.ValidationException.class, customValidationExceptionSerializer());  
        return customJacksonModule;
    

我尝试了几种方法,但到目前为止都没有成功:

1.应用程序.properties

我将spring.jackson.serialization.write-date-timestamps-as-nanoseconds = false 放入了我的 application.propreties

2。自定义对象映射器

我尝试更改 objectMapper 的设置。

@Autowired(required = true)
public void configureJackson(ObjectMapper jackson2ObjectMapper) 
    jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    jackson2ObjectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);

3.删除了@EnableHypermediaSupport

@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)

所有这些操作都没有改变日期返回给客户的方式。我想要一些建议来理解/调试为什么日期没有以正确的格式返回。

作为补充说明,我发现在com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializerBase in serialize() 方法中我既没有useNanoseconds 属性,也没有默认formatter。 但是 application.properties 中的属性spring.jackson.serialization.write-dates-as-timestamps 对日期格式有影响。

【问题讨论】:

【参考方案1】:

您是否尝试使用@JsonFormat 注释您的validUntil 字段,如下所示。

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
@NotNull
@Column(nullable = false)
private Instant validUntil;

【讨论】:

它有效,但我应该在我的应用程序的每个字段上添加该注释。我想在配置级别为整个应用程序做一些事情【参考方案2】:

您可以将 ObjectMapper 配置为跨应用程序使用特定的日期格式:

jackson2ObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz"));

【讨论】:

我试过了,但在我的情况下它并没有改变格式。 它不适用于java.time 类型。【参考方案3】:

您需要替换 InstantSerializer 正在被 Jackson 使用。

@Configuration
public class JacksonConfig 

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() 
        return builder -> builder.serializers(new CustomInstantSerializer());
    

    private static class CustomInstantSerializer extends InstantSerializer 

        private static final DateTimeFormatter UTC_DATE_FORMAT = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneOffset.UTC);

        private CustomInstantSerializer() 
            super(InstantSerializer.INSTANCE, null, UTC_DATE_FORMAT);
        

    


例如,可以将JacksonConfig类放在项目的config包中。

另外,如果它不起作用,请检查 SpringBoot 是否真的可以找到它。在InstantSerializer 的默认构造函数中设置断点或在此处添加临时日志记录。

【讨论】:

以上是关于Spring Boot,在 REST 响应中将日期时间精度定义为毫秒的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring(Boot)中装饰 REST 响应?

在 Spring Boot jpa 中将延迟加载的对象转换为 JSON

如何在Spring Boot Rest API中的BeanUtils.copyProperties中将String转换为枚举

Spring Boot REST 验证错误响应

如何在 Spring Boot Rest api 响应的 ResponseEntity 中添加自定义属性

Spring Boot REST API 返回 XML 作为响应