[Spring boot] 날짜 타입 JSON 변환
크게 신경 쓰고 있지않았던 날짜관련 클래스와 어노테이션이 생각보다 오류를 처리하는데 발목을 잡아서
어노테이션까지 정리를 해보도록 해야겠다. 생각보다 이런부분에서 구멍이 있다면 참 많은 시간을 잡아 먹는구나를 알게 되었다. 열심히 공부해야지!
정리할 내용 : REST API에서 사용하는 날짜 포맷
- 직렬화를 하지 못하면 오류가 발생한다.
- String으로 받지말기.....
1. @DateTimeFormat
- Spring에서 지원하는 어노테이션으로 LocalData / LocalDateTime과 같은 날짜 관련타입의 직렬화를 지원하는 어노테이션이다.
- GET 요청시 Request Body에서 사용.(RequestParmeter에서도 사용한다)
- POST 요청시 Request Body에서도 사용.
<조건>
- 두 어노테이션 모두가 있으면 @JsonFormat이 진행된다
- @JsonFormat이 틀리면 @DateTimeFormat이 맞더라도 직렬화는 실패한다
- 단, @DateTimeFormat이 있다면 @DateTimeFormat의 포맷으로 직렬화가 진행된다.
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime startDay;
@GetMapping("/request")
public String requestMethod(
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
@RequestParam("requestdatetime") LocalDateTime requestdatetime) {
})
- 패턴사용시
@DateTimeFormat(pattern="yyyyMMddHHmmss")
2. @JasonFormat
- Jackson의 어노테이션(JSON을 변환 할때 사용)
- LocalDate / LocalDateTime을 JSON으로 직렬화 할때 포맷을 관리한다.
- Post요청시 RequestBody와 ReponseBody에서 사용.
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startDay;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private LocalDate birthDay;
** POST로 보내는 Request Body(Json 객체)는 @DateTimeFormat과 @JsonFormat 모두 사용할 수 있다.
** ResponseBody에서는 @JsonFormat만 가능하다.
3. 이유
JSON으로 변환을 할때 Jackson을 통해서 진행되는데,
Jackson은 Spring의 어노테이션인 @DateTimeFormat 을 알수 없기 때문에(서로 다른 라이브러리) @DateTimeFormat을 지정했다 하더라도, Jackson은 이 어노테이션을 전혀 고려하지 않고 JSON 직렬화을 진행하게된다. -> 에러 발생.
따라서 Response로 JSON으로 변환해 직렬화 시킬땐 @JsonFormat을 사용해야한다.
( JSON 직렬화 과정에서 @JsonFormat이 없다면 Spring에서는 @DateTimeFormat를 통해 직렬화를 진행하기때문에 post요청에서는 두 어노테이션이 모두 사용가능한것이다.)
반대로, JSON직렬화 외에는 jackson이 사용되지않기때문에 @JsonFormat은 효과가 없다.
따라서 RequestParameter나 ModelAttribute에선 @DateTimeFormat 만 적용될 수 있는 것이다.
4. 정리
- Response (서버 -> 클라이언트) 로 전달할 때에는 @JsonFormat 을 사용,
- Request(클라이언트 -> 서버)로 전달할 때는 @DateTimeFormat 을 사용한다.
(post요청시 request에서는 @jsonFormat 사용 가능) - Post 요청시에도 @DateTimeFormat이 적용될 수 있으나, @JsonFormat이 지정되어 있지않을 때만 가능하다.
- JsonFormat을 사용했을때 직렬화에 실패한다면 DateTimeFormat을 사용하자
- Spring Boot 2.0에서는 JSR 310이 기본 의존성에 포함되어있다.(이것은 잘모름...)
<참고 블로그>
https://jojoldu.tistory.com/361
SpringBoot에서 날짜 타입 JSON 변환에 대한 오해 풀기
안녕하세요? 이번 시간엔 Spring과 JSON에 대해 정리해보려고 합니다. 모든 코드는 Github에 있기 때문에 함께 보시면 더 이해하기 쉬우실 것 같습니다. (공부한 내용을 정리하는 Github와 세미나+책 후
jojoldu.tistory.com