ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 포맷터 - Formatter
    스프링/스프링 MVC 패턴 2023. 3. 7. 17:12

    보통 문자 -> 다른 타입 혹은 다른 타입 -> 문자의 변환을 많이 사용한다.

    스프링에서는 포맷터라는 문자의 자동 변환 기능을 제공한다.

     

     

    MyNumberFormatter.class

    @Slf4j
    public class MyNumberFormatter implements Formatter<Number> {
    
        // Number는 integer, double, long 등 숫자 형태 타입의 부모
        @Override
        public Number parse(String text, Locale locale) throws ParseException {
            log.info("text={}, locale={}", text, locale);
            // "1,000" -> 1000
            NumberFormat format = NumberFormat.getInstance(locale);
            Number parse = format.parse(text);
            return parse;
        }
    
        @Override
        public String print(Number object, Locale locale) {
            log.info("object={}, locale={}", object, locale);
            NumberFormat instance = NumberFormat.getInstance(locale);
            String format = instance.format(object);
            return format;
        }
    }

    Formatter을 implements를 한 구현체에서 parse와 print 2가지의 메서드를 구현할 수 있다.

    변환을 할 객체의 타입과 Locale을 파라미터로 갖는다.

    NumberFormate으로 locale의 instance를 받아오고, parse는 parse를, print는 format을 이용해서 객체 타입을 바꾼 다음에 return 해주면 된다.

     

     

    포맷터의 적용

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new StringToIpPortConverter());
            // registry.addConverter(new StringToIntegerConverter());
            registry.addConverter(new IpPortToStringConverter());
            // registry.addConverter(new IntegerToStringConverter());
    
            // 포맷터 추가
            registry.addFormatter(new MyNumberFormatter());
        }
    }

    WebConfig에 registry.addFormatter(new MyNumberFormatter());를 이용해 포맷터를 추가해주었다.

    이전에 해줬던 addConverter의 주석 2개는 우선순위때문에 주석처리 해 준 것이다.

     

     

     

    localhost:8080/hello-v2?data=10,000 로 파라미터를 넘겨주면

    @GetMapping("/hello-v2") // 이전에 만들었던 매핑 메서드
    public String helloV2(@RequestParam Integer data) {
        System.out.println("data = " + data);
        return "ok";
    }

    2023-03-07T16:56:47.403+09:00  INFO 4988 --- [nio-8080-exec-5] h.t.formatter.MyNumberFormatter          : text=10,000, locale=ko
    data = 10000

    라는 로그가 찍힌다.

    data로 들어올 때 문자가 아닌 integer 타입으로 들어온 것을 확인할 수 있었다.

     

     

     

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

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

     

    @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.html";
        }
    
        @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;
        }
    }

    포맷터를 사용하는 클래스이다. Form이라는 객체를 만들고 @NumberFormat, @DateTimeFormat 애노테이션을 사용하고 패턴을 지정해주면 해당 형태로 타입을 변환시켜준다.

     

     

    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>

     

    타입변환이 자동으로 잘 이루어진다.

     

    나중에 타입 변환이 필요해서 컨버터를 사용해야할 때가 있을텐데 직접 만들어서 하기에는 번거로우니까 스프링에서 제공하는 포맷터를 사용하면 효율적으로 개발을 할 수 있을 것이라 생각된다.

Designed by Tistory.