使用 JSON 使用 Spring Boot 格式化 Java 时间 [重复]

Posted

技术标签:

【中文标题】使用 JSON 使用 Spring Boot 格式化 Java 时间 [重复]【英文标题】:Formatting Java Time with Spring Boot using JSON [duplicate] 【发布时间】:2019-12-16 05:06:54 【问题描述】:

我想在 Spring Boot v1.5.14.RELEASE 应用中实现自定义验证器。首先我创建一个自定义约束注解:

我有这个对象:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuperBuilder
public class Hotel 

    @JsonFormat(pattern = "yyyy-MM-dd")
    private OffsetDateTime interactionDurationStart;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private OffsetDateTime interactionDurationEnd;


在 yml 中:

spring:
  jackson:
    mapper:
      DEFAULT_VIEW_INCLUSION: true
    serialization:
      WRITE_DATES_AS_TIMESTAMPS: false

在我的配置文件中:

@Primary
@Bean
public ObjectMapper objectMapper() 

    ObjectMapper objectMapper = new ObjectMapper();
    //objectMapper.registerModule(new JavaTimeModule());
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() 
        @Override
        public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException 
            jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(offsetDateTime));
        
    );
    objectMapper.registerModule(simpleModule);

    return objectMapper;

但这是我在 API 响应中看到的

"interactionDurationEnd" : 
      "offset" : 
        "totalSeconds" : 7200,
        "id" : "+02:00",
        "rules" : 
          "transitionRules" : [ ],
          "transitions" : [ ],
          "fixedOffset" : true
        
      ,

【问题讨论】:

【参考方案1】:

这是因为 spring 使用的 ObjectMapper 默认只识别 Date 。如果您想使用 OffsetDateTime 字段,请查看此Jackson date-format for OffsetDateTime in Spring Boot,因为您需要注册一个序列化器/反序列化来为您完成这项工作。

如果您想将字段类型更改为日期,那么我不确定 JsonFormat 是否可以工作,因为我从未使用过它。我对这个案例的解决方案是提供一个 ObjectMapper bean 来使用 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")) 来实现这一点。

希望有所帮助!

【讨论】:

【参考方案2】:

jackson-databind 的哪个版本?

尝试添加形状

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-mm-dd")

如果它有效,那么您的问题是旧版本的 jackson-bind 存在错误,需要使用形状,或者默认情况下它将是任何形状。

【讨论】:

【参考方案3】:

Spring MVC 使用 Jackson 作为默认的 json 对象映射器。 Jackson 默认不支持 java8 的 Time API 的序列化/反序列化,但它提供了一个模块来集成它。只需将此依赖项包含在您的 pom.xml 中即可:

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
  </dependency>

Spring Boot 自动配置将检测 Jackson 模块类 JavaTimeModule 并将其添加到 ObjectMapper 实例中。

如果您手动创建 ObjectMapper 实例,则可以使用以下行添加模块:

objectMapper.registerModule(new JavaTimeModule());

【讨论】:

这不是我的家乡,但我的印象是jackson-datatype-jsr310被合并到jackson-modules-java8中,现在你应该更喜欢使用后者。

以上是关于使用 JSON 使用 Spring Boot 格式化 Java 时间 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSON 使用 Spring Boot 格式化 Java 时间 [重复]

如何使用 thymeleaf 和 Spring Boot 以 json 格式显示用户输入数据

在 Spring Boot、Hibernate 中使用 @Query 注解以 JSON 格式(键值对)查询结果

如何使用 MySQL 在 Spring Boot REST API 中放置和获取任何格式的 JSON 对象?

Spring Boot返回Json数据及数据封装

如何在 Spring Boot REST API 中格式化返回的 json?