Date Parsing in Spring Boot RestTemplate DTO

@ZungTa · 2024-01-09 화요일 · 2 min read

에러 발생
해결 과정
References

에러 발생

외부 API를 이용해서 데이터를 받아오는 로직을 추가하고 있었다.

API Response Body DTO를 작성해서 RestTemplate을 이용하여 API 요청을 하고 응답을 받았는데 DTO로 Parsing 하던 중 에러가 발생했다.

Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [-] and content type [application/json;charset=UTF-8]

해결 과정

해당 에러를 검색해보니 자료가 좀 있었는데, 나랑은 상황이 좀 다른 글들이 많았다. (e.g. PutMappingPostMapping으로 바꾸니까 해결)

아마 이 에러가 포함하고 있는 에러 상황이 포괄적인듯하다.

하지만 나는 JSON을 Class로 deserialize 하던 과정에서 에러가 발생했다고 거의 확신했기 때문에 디버깅을 하였다.

어느 property를 parsing할 때 에러가 발생하는지 알아야 했기 때문이다. (DTO의 property가 많아서 거의 150줄이었다.)

RestTemplate.exchangeRestTemplate.executeRestTemplate.doExecuteRestTemplate.extractDataHttpMessageConverterExtractor.extractDataAbstractJackson2HttpMessageConverter.readAbstractJackson2HttpMessageConverter.readJavaTypeObjectReader.readValueObjectReader._bindAndCloseDefaultDeserializationContext.readRootValueBeanDeserializer.deserializeBeanDeserializer.deserializeFromObjectFieldProperty.deserializeAndSetCollectionDeserializer._deserializeFromArrayDateDeserializers._parseDateStdDeserializer._parseDateDeserializationContext.parseDateStdDateFormat.parse

대략 이런 식으로 parsing 과정을 타고 타고 들어가서 어느 property에서 에러가 발생하는지 확인할 수 있었다.

실제로는 저렇게 깊게 들어가진 않았고 날짜를 parsing할 때 에러가 발생한다는 것 까지만 파악 후 관련 내용을 검색했다.

API 응답으로 들어온 날짜 형식의 문자열 값인 2024-01-04 16:52:22을 Java의 Date 형식으로 만들어줄 때 에러가 발생했다.

Java의 기본적인 date formatter랑 형식이 일치하지 않는 것 같다.

그리고 생각해보니 어느정도 당연한 에러라고 생각했다. 막연히 Framework에서 알아서 Date로 변환해줄 거라고 생각을 했는데 각 API 응답마다 보내주는 date string 형식이 충분히 다를 수 있고 그걸 다 알아서 변환해 줄 수는 없는게 당연하다고 느꼈다.

그래서 Spring Boot RestTemplate Date Format으로 검색해보니 뭔가 document 사이트 같은 곳이 있어서 그곳을 참고했다.

@JsonFormat Annotation을 활용해서 Date String이 어떤 형식으로 들어올 것인지 미리 지정해 줄 수 있다.

@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
Date registerDate;

그리고 나는 저렇게 적용했을 때 parsing은 에러 없이 잘 진행되었지만 Date의 시간이 다르게 나왔다.

9시간 차이나는 것으로 보아 타임존 문제로 추측하고 timezone 설정도 찾아서 적용했다.

@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "Asia/Seoul")
Date registerDate;

이렇게 재밌고 눈이 아픈 디버깅 시간을 통해 DTO의 수많은 property를 일일이 확인해보지 않고 빠르게 해결할 수 있었다.

References

@ZungTa
I'm a backend developer
© ZungTa Devlog, Built with Gatsby