[java] Spring Boot의 JSON Java 8 LocalDateTime 형식

Spring Boot Application에서 Java 8 LocalDateTime을 형식화하는 데 작은 문제가 있습니다. ‘정상’날짜에는 문제가 없지만 LocalDateTime 필드는 다음과 같이 변환됩니다.

"startDate" : {
    "year" : 2010,
    "month" : "JANUARY",
    "dayOfMonth" : 1,
    "dayOfWeek" : "FRIDAY",
    "dayOfYear" : 1,
    "monthValue" : 1,
    "hour" : 2,
    "minute" : 2,
    "second" : 0,
    "nano" : 0,
    "chronology" : {
      "id" : "ISO",
      "calendarType" : "iso8601"
    }
  }

다음과 같이 변환하고 싶습니다.

"startDate": "2015-01-01"

내 코드는 다음과 같습니다.

@JsonFormat(pattern="yyyy-MM-dd")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
public LocalDateTime getStartDate() {
    return startDate;
}

그러나 위의 주석 중 하나가 작동하지 않고 날짜가 계속 위와 같은 형식으로 지정됩니다. 제안을 환영합니다!



답변

업데이트 : Spring Boot 2.x는 더 이상이 구성이 필요하지 않습니다. 여기에 더 최신 답변을 썼습니다 .


(이것은 Spring Boot 2.x 이전에 수행하는 방법이며 이전 버전의 Spring Boot에서 작업하는 사람들에게 유용 할 수 있습니다.)

나는 마침내 여기에서 그것을하는 방법을 찾았 습니다. 이를 수정하려면 다른 종속성이 필요했습니다.

compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.4.0")

이 종속성을 포함함으로써 Spring은 여기에 설명 된대로 자동으로 변환기를 등록합니다 . 그런 다음 application.properties에 다음을 추가해야합니다.

spring.jackson.serialization.write_dates_as_timestamps=false

이렇게하면 올바른 변환기가 사용되며 날짜는 다음 형식으로 인쇄됩니다. 2016-03-16T13:56:39.492

주석은 날짜 형식을 변경하려는 경우에만 필요합니다.


답변

com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1종속성을 추가하고 다음 형식으로 날짜를 가져 오기 시작했습니다.

"birthDate": [
    2016,
    1,
    25,
    21,
    34,
    55
  ]

내가 원했던 것은 아니지만 점점 더 가까워졌습니다. 그런 다음 다음을 추가했습니다.

spring.jackson.serialization.write_dates_as_timestamps=false

필요한 올바른 형식을 제공하는 application.properties 파일에.

"birthDate": "2016-01-25T21:34:55"


답변

여기는 maven에 있으며 속성이 있으므로 봄 부팅 업그레이드 사이에서 살아남을 수 있습니다.

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
</dependency>


답변

1) 의존성

 compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.8.8' 

2) 날짜-시간 형식의 주석.

public class RestObject {

    private LocalDateTime timestamp;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public LocalDateTime getTimestamp() {
        return timestamp;
    }
}

3) 스프링 구성.

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        System.out.println("Config is starting.");
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }
}


답변

원하는 형식으로 변환하고 모든 LocalDateTime 데이터 유형에 적용 할 수있는 또 다른 솔루션을 찾았으며 모든 LocalDateTime 데이터 유형 위에 @JsonFormat을 지정할 필요가 없습니다. 먼저 종속성을 추가하십시오.

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

다음 빈을 추가하십시오.

@Configuration
public class Java8DateTimeConfiguration {
    /**
     * Customizing
     * http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html
     *
     * Defining a @Bean of type Jackson2ObjectMapperBuilder will allow you to customize both default ObjectMapper and XmlMapper (used in MappingJackson2HttpMessageConverter and MappingJackson2XmlHttpMessageConverter respectively).
     */
    @Bean
    public Module jsonMapperJava8DateTimeModule() {
        val bean = new SimpleModule();

        bean.addDeserializer (ZonedDateTime.class, new JsonDeserializer<ZonedDateTime>() {
            @Override
            public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return ZonedDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
            }
        });

        bean.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return LocalDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            }
        });

        bean.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
            @Override
            public void serialize(
                    ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime));
            }
        });

        bean.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
            @Override
            public void serialize(
                    LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime));
            }
        });

        return bean;
    }
}

구성 파일에 다음을 추가하십시오.

@Import(Java8DateTimeConfiguration.class)

이것은 Spring에서 만든 objectMapper를 사용하는 한 모든 속성 LocalDateTime 및 ZonedDateTime을 직렬화 및 역 직렬화합니다.

ZonedDateTime의 형식은 “2017-12-27T08 : 55 : 17.317 + 02 : 00 [Asia / Jerusalem]”(LocalDateTime) : “2017-12-27T09 : 05 : 30.523″입니다.


답변

이 답변을 저에게도 상기시켜줍니다.

나는 여기에 몇 가지 답변을 결합했으며 결국에는 이와 같은 작업을 수행했습니다. (SpringBoot 1.5.7 및 Lombok 1.16.16을 사용하고 있습니다)

@Data
public Class someClass {

   @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
   @JsonSerialize(using = LocalDateTimeSerializer.class)
   @JsonDeserialize(using = LocalDateTimeDeserializer.class)
   private LocalDateTime someDate;

}


답변

이것은 잘 작동합니다.

종속성을 추가하십시오.

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

주석을 추가하십시오.

@JsonFormat(pattern="yyyy-MM-dd")

이제 올바른 형식을 가져와야합니다.

객체 매퍼를 사용하려면 JavaTime을 등록해야합니다.

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());