오봉이와 함께하는 개발 블로그

스프링 MVC 2 - 스프링이 제공하는 기본 포맷터 본문

BE/Spring

스프링 MVC 2 - 스프링이 제공하는 기본 포맷터

오봉봉이 2022. 9. 1. 00:43
728x90

스프링이 제공하는 기본 포맷터

스프링은 자바에서 기본으로 제공하는 타입들에 대해 수 많은 포맷터를 기본으로 제공한다.
IDE에서 Formatter인터페이스의 구현 클래스를 찾아보면 수 많은 날짜나 시간 관련 포맷터가 제공되는 것을 확인할 수 있다.
그런데 포맷터는 기본 형식이 지정되어 있기 때문에, 객체의 각 필드마다 다른 형식으로 포맷을 지정하기는 어렵다.

스프링은 이런 문제를 해결하기 위해 어노테이션 기반으로 원하는 형식을 지정해서 사용할 수 있는 매우 유용한 포맷터 두 가지를 기본으로 제공한다.

  • @NumberFormat : 숫자 관련 형식 지정 포맷터 사용, NumberFormatAnnotationFormatterFactory
  • @DateTimeFormat : 날짜 관련 형식 지정 포맷터 사용, Jsr310DateTimeFormatAnnotationFormatterFactory

우선순위가 직접 만든 포맷터나 타입 컨버터이기 때문에 WebConfig에서 @Configuration을 주석처리 하자.

FormatterController

@Controller
public class FormatterController {

    @GetMapping("/formatter/edit")
    public String formatterForm(Model model) {
        Form form = new Form();
        form.setNumber(10000);
        form.setLocalDateTime(LocalDateTime.now());

        model.addAttribute("form", form);
        return "formatter-form";
    }

    @PostMapping("/formatter/edit")
    public String formatterEdit(@ModelAttribute Form form) {
        return "formatter-view";
    }

    @Data
    static class Form {
        @NumberFormat(pattern = "###,###")
        private Integer number;

        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime localDateTime;
    }
}

templates/formatter-form.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form th:object="${form}" th:method="post">
    number <input type="text" th:field="*{number}"><br/>
    localDateTime <input type="text" th:field="*{localDateTime}"><br/>
    <input type="submit"/>
</form>

</body>
</html>

templates/formatter-view.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<ul>
    <li>${form.number}: <span th:text="${form.number}" ></span></li>
    <li>${{form.number}}: <span th:text="${{form.number}}" ></span></li>
    <li>${form.localDateTime}: <span th:text="${form.localDateTime}" ></span></li>
    <li>${{form.localDateTime}}: <span th:text="${{form.localDateTime}}" ></span></li>
</ul>

</body>
</html>

실행

number 10,000
localDateTime 2022-09-01 00:35:32

실행

${form.number}: 10000
${{form.number}}: 10,000
${form.localDateTime}: 2022-09-01T00:35:32
${{form.localDateTime}}: 2022-09-01 00:35:32
@Data
static class Form {
    @NumberFormat(pattern = "###,###")
    private Integer number;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime localDateTime;
}

@ModelAttribute Form form가 있어 Form에 데이터를 넣으려고 보니 @NumberFormat(pattern = "###,###")@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")가 적용되어 있기 때문에 formatter-view.html에도 적용이 된다.

참고

@NumberFormat, @DateTimeFormat의 자세한 사용법이 궁금하면 다음 링크를 참고하거나 관련
어노테이션을 검색해보자.

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#format-CustomFormatAnnotations

정리

컨버터를 사용하든, 포맷터를 사용하든 등록 방법은 다르지만, 사용할 때는 컨버전 서비스를 통해서 일관성 있게 사용할 수 있다.

주의!!!

메시지 컨버터(HttpMessageConverter)에는 컨버전 서비스가 적용되지 않는다.
특히 객체를 JSON으로 변환할 때 메시지 컨버터를 사용하면서 이 부분을 많이 오해한다.
HttpMessageConverter 의 역할은 HTTP 메시지 바디의 내용을 객체로 변환하거나 객체를 HTTP 메시지 바디에 입력하는 것이다.
예를 들어서 JSON을 객체로 변환하는 메시지 컨버터는 내부에서 Jackson 같은 라이브러리를 사용한다.
객체를 JSON으로 변환한다면 그 결과는 이 라이브러리에 달린 것이다.
따라서 JSON 결과로 만들어지는 숫자나 날짜 포맷을 변경하고 싶으면 해당 라이브러리가 제공하는 설정을 통해서 포맷을 지정해야 한다.
결과적으로 이것은 컨버전 서비스와 전혀 관계가 없다.

컨버전 서비스는 @RequestParam, @ModelAttribute, @PathVariable, 뷰 템플릿등에서 사용할 수 있다.

출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
728x90
Comments