programing

스프링 부트 로컬 날짜 필드 직렬화 및 역직렬화

sourcejob 2023. 7. 23. 14:12
반응형

스프링 부트 로컬 날짜 필드 직렬화 및 역직렬화

Spring Boot 1.2.3에서.fasterxml을 사용한 릴리스 직렬화 및 직렬화 해제의 올바른 방법은 무엇입니까?LocalDate필드를 ISO 날짜 형식 문자열로 지정하시겠습니까?

시도해 봤습니다.

  • spring.jackson.serialization.write-dates-as-timestamps:falseapplication.properties 파일에서

  • 프로젝트에 Jackson-datatype-jsr310을 포함한 다음 사용합니다.

    • @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")주석

    • 그리고.@DateTimeFormat(iso=ISO.DATE)주석,

  • 추가Jsr310DateTimeFormatAnnotationFormatterFactory형식 지정:

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
    }
    

위의 어떤 것도 도움이 되지 않았습니다.

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

build.gradle 및 다음 주석이 도움이 되었습니다.

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthday;

업데이트: Spring Boot 2.*를 사용하는 경우 "시작" 중 하나를 통해 종속성이 이미 포함되어 있습니다.

내 Spring Boot 2 응용 프로그램에서

  • @JsonFormat주석은 JSON 데이터를 직렬화(해제)할 때 REST 컨트롤러에서 사용됩니다.
  • @DateTimeFormat주석이 다른 컨트롤러에서 사용됨ModelAttributes 문자열 데이터를 serialize(직렬화)할 때.

동일한 필드에서 둘 다 지정할 수 있습니다(JSON 및 Thymeleaf 템플릿 간에 DTO를 공유하는 경우 유용).

@JsonFormat(pattern = "dd/MM/yyyy") 
@DateTimeFormat(pattern = "dd/MM/yyyy")
private LocalDate birthdate;

그라들 종속성:

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-json'

Spring Boot 2.x 앱에서 사용자 지정 날짜/시간 형식을 지정하는 데 필요한 구성이 이것뿐이기를 바랍니다.


Spring Boot 1.x 앱의 경우 추가 주석 및 종속성을 지정합니다.

@JsonFormat(pattern = "dd/MM/yyyy")
@DateTimeFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthDate;

// or
@JsonFormat(pattern = "dd/MM/yyyy HH:mm")
@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime birthDateTime;
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.8'

다른 사람이 잘못된 형식으로 날짜를 보내면 API에서 "JSON 구문 분석 오류"가 발생합니다.매핑 예:

@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate releaseDate;

예외 예:

HttpMessageNotReadableExceptionJSON 구문 분석 오류: 형식 값을 역직렬화할 수 없습니다.java.time.LocalDate문자열 "2002"에서:역직렬화 실패java.time.LocalDate: (java.time.format.DateTimeParseException) '2002' 텍스트를 인덱스 4에서 구문 분석할 수 없습니다. 중첩 예외:com.fasterxml.jackson.databind.exc.InvalidFormatException형식 값을 역직렬화할 수 없습니다.java.time.LocalDate문자열 "2002"에서:역직렬화 실패java.time.LocalDate: (java.time.format.DateTimeParseException인덱스 4에서 '2002' 텍스트를 구문 분석할 수 없습니다.

사용자 지정 Java Date 포맷터를 사용하려면 다음을 추가합니다.@JsonFormat주석

@JsonFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthdate;*

실제로 pom.xml에 종속성을 지정하면 작동합니다.

이렇게 하면 모든 로컬 날짜 필드가 자동으로 ISO 형식을 사용하므로 주석을 달 필요가 없습니다.

<!-- This is enough for LocalDate to be deserialized using ISO format -->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

Spring Boot 1.5.7에서 테스트되었습니다.

모든 LocalDate 특성에 대해 serializer/deserializer를 지정하는 대신 전체적으로 등록할 수 있습니다.직렬화/직렬화를 위해 Spring에서 사용하는 기본 ObjectMapper의 구성을 재정의해야 합니다.다음은 예입니다.

@Configuration
public class ObjectMapperConfiguration {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();

        // Registro global do serializer/deserializer para datas sem horário
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer());
        simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());

        mapper.registerModule(simpleModule);
        return mapper;
    }
}

이렇게 하면 잭슨은 항상 클래스 속성에 주석을 달 필요 없이 정의된 데이터 유형에 대해 지정된 직렬화/직렬화를 사용합니다.

정보: 사용자 지정 serializer/deserializer 코드 기능을 사용하려면 pom.xml에 jackson-databind 종속성을 추가해야 합니다.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>
 @Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    return builder -> {
        DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        builder.serializerByType(LocalDate.class, new LocalDateSerializer(localDateFormatter));
        builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(localDateFormatter));

        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
        builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));
    };
}

언급URL : https://stackoverflow.com/questions/30871255/spring-boot-localdate-field-serialization-and-deserialization

반응형