2 분 소요

 인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.

포맷터 적용하기

포맷터를 웹 어플리케이션에 적용해 보자.

WebConfig - 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration  
public class WebConfig implements WebMvcConfigurer {  
  
    @Override  
    public void addFormatters(FormatterRegistry registry) {  
        // 주석처리 우선순위  
        //registry.addConverter(new StringToIntegerConverter());  
        //registry.addConverter(new IntegerToStringConverter());
        registry.addConverter(new StringToIpPortConverter());  
        registry.addConverter(new IpPortToStringConverter());  
  
        registry.addFormatter(new MyNumberFormatter());  
    }  

1
registry.addFormatter(new MyNumberFormatter());

addFormatter로 추가해주면 된다.

주의
StringToIntegerConverter, IntegerToStringConverter를 꼭 주석 처리 하자.

MyNumberFormatter도 숫자 ↔ 문자 이기 때문에 두 컨버터와 역할이 겹친다.

우선 순위는 컨버터가 우선이므로 포맷터가 적용이 안된다.

실행

  • http://localhost:8080/converter-view

$에서 내가 원하는 10,000이 됐다.

이번엔 반대로 문자를 숫자로 바꾸는 것도 잘 되는 지 확인해 보자.

  • http://localhost:8080/hello-v2?data=10,000

data에 문자 10,000을 넘겼다.

포맷터가 작동하면서 숫자 10000이 정상적으로 출력된다.

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

스프링은 자바에서 기본으로 제공하는 타입들에 대해 수 많은 포맷터를 기본으로 제공한다.

IDE에서 Formatter인터페이스의 구현 클래스를 찾아보면 수 많은 날짜나 시간 관련 포맷터가 제공되는 것을 확인할 수 있다.

그런데 포맷터는 기본 형식이 지정되어 있기 때문에, 객체의 각 필드마다 다른 형식으로 포맷을 지정하기 어렵다.

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

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

예제

hello.typeconverter.controller.FormatterController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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 form) {  
        return "formatter-view";  
    }  
  
  
    @Data  
    static class Form {  
        @NumberFormat(pattern = "###,###")  
        private Integer number;  
  
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")  
        private LocalDateTime localDateTime;  
    }  
}
1
2
3
4
5
@NumberFormat(pattern = "###,###")  
private Integer number;  

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

여기서 @NumberFormat은 숫자를 문자로 바꿔주는데, 3 자리 마다 ,를 넣어 준다.

@DateTimeFormat는 날짜를 2024-07-02 08:25:12 다음과 같은 문자열로 바꿔줄 것이다.

물론 반대로도 마찬가지다.

뷰 템플릿을 만들자.

templates/formatter-form.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!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>

th:field는 자동으로 컨버팅 해준다.

templates/formatter-view.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!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>$: <span th:text="$" ></span></li>  
    <li>${form.localDateTime}: <span th:text="${form.localDateTime}" ></span></li>  
    <li>$: <span th:text="$" ></span></li>  
</ul>  
  
</body>  
</html>

숫자와 날짜 객체를 넘겼는데 내가 의도한 대로 문자열로 잘 바뀌었다.

그럼 이걸 다시 제출하면

1, 3 번째가 숫자, 날짜 객체라는 것을 알 수 있다.

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

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

참고
@NumberFormat, @DateTimeFormat의 자세한 사용법은 다음 링크를 참고하자.

댓글남기기