프론트가 업무가 많아짐에 따라 가격과 날짜 같은 경우 내가 보기 좋은 형식으로 프론트에게 주고 싶어졌다.
FE는 결국 화면에 중요하게 시간을 사용해야하므로
BE인 내가 사용하기 좋은 포맷으로 포맷팅을 해주고싶었다.
Spring에는 다양한 Formatter를 제공한다.
그 중 유용한 포맷터인
@NumberFormat
: 숫자관련 포맷터 사용@DateTimeFormat
: 날짜관련 포맷터 사용를 제공한다.
하지만 해당 Formatter에는 큰 사용 불가한 점이 있다.
메세지 컨버터에는 해당 기능이 사용 불가하다.
사실 포맷터는 한곳에서 모아서 사용이 가능한지 판단해주는 Conversion
인터페이스에 등록되고 사용이 된다.
하지만
HttpMessageConverter 의 역할은 HTTP 메시지 바디의 내용을 객체로 변환하거나 객체를 HTTP 메시지 바디에 입력하는 것이다.
예를 들어서 JSON을 객체로 변환하는 메시지 컨버터는 내부에서 Jackson 같은 라이브러리를 사용한다.
객체를 JSON으로 변환한다면 그 결과는 이 라이브러리에 달린 것이다. 따라서
JSON 결과로 만들어지는 숫자나 날짜 포맷을 변경하고 싶으면 해당 라이브러리가 제공하는 설정을 통해서 포맷을 지정해야 한다.
결과적으로 이것은 컨버전 서비스와 전혀 관계가 없다.
컨버전 서비스는 @RequestParam
, @ModelAttribute
, @PathVariable
, 뷰 템플릿(타임리프, jsp)
등에서 사용할 수
있다
그렇다면 스프링 메세지 컨버터는 어떤 라이브러리를 사용하고 있을까?
Spring MVC인 spring-boot-starter-web
에는 Jackson를 포함하고있다.
공식문서의 내용으로 일반적으로 Date타입을 Number 혹은 String 형식으로 직렬화 하는데 사용하고,
pattern() property을 통해 정확한 세부설정을 하기위해 사용한다고 한다.
@JsonFormat
을 통해 사용가능하다
공식 문서와 사용 레퍼런스
https://www.baeldung.com/jackson-jsonformat
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date regDate;
스프링은 이러한 반복되는 작업에서 굉장히 최적화가 잘되어있습니다.
고로 해당 번거로운 작업을 전체적으로 해줄 수 있습니다.
@Configuration
public class DateFormatConfiguration {
private static final String dateFormat = "yyyy-MM-dd";
private static final String datetimeFormat = "yyyy-MM-dd HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){
return jacksonObjectMapperBuilder -> {
jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("UTC"));
jacksonObjectMapperBuilder.simpleDateFormat(datetimeFormat);
jacksonObjectMapperBuilder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
jacksonObjectMapperBuilder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(datetimeFormat)));
};
}
}
여기서는 날짜 형식만 다루지만 이외에도 다른 Json응답값을 설정하고 변경할 수 있다.
하지만 여기서 스프링의 기본원칙
- 더 유연한 것이 우선권을 가진다.
- 범위가 넒은 것 보다 좁은 것이 우선권을 가진다.
그래서 만약 저렇게 전체적인 Json에 대한 포맷팅을 설정했어도
해당 필드위에
@JsonFormat(pattern = "yyyy.MM.dd")
private Date regDate;
라고 지정했으면
2023-03-31
이 아닌 2023.03.31
로 나오게 된다.
@ModelAttribte, @RequestParam
@RequestBody
@ReponseBody
FE에게 일관적인 날짜 포맷을 제공하여 편리하게 사용하도록하였다.
https://develop-writing.tistory.com/106
https://addio3305.tistory.com/101
https://dev-monkey-dugi.tistory.com/m/160