# ํฌ๋งทํ„ฐ(Formatter)
Study Repository

ํฌ๋งทํ„ฐ(Formatter)

by rlaehddnd0422

ํฌ๋งทํ„ฐ

์ปจ๋ฒ„ํ„ฐ๋Š” ์ž… ์ถœ๋ ฅ ํƒ€์ž…์— ์ œํ•œ์ด ์—†์ด ๋ฒ”์šฉ์ ์œผ๋กœ ํƒ€์ž…์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. 

ํฌ๋งทํ„ฐ๋Š” ์ปจ๋ฒ„ํ„ฐ ๊ธฐ๋Šฅ์—์„œ ์กฐ๊ธˆ ๋” ํŠนํ™”๋œ ๊ธฐ๋Šฅ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž๋กœ, ๋ฌธ์ž๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ€ ๋•Œ Locale ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ํ˜„์ง€ํ™” ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํฌ๋งทํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค

public interface Formatter<T> extends Printer<T>, Parser<T> {}
@FunctionalInterface
public interface Printer<T> {
   String print(T object, Locale locale);
}
@FunctionalInterface
public interface Parser<T> {
   T parse(String text, Locale locale) throws ParseException;
}

๋ฉ”์†Œ๋“œ ์„ค๋ช…

  • String print(T object , Locale locale) : Object๋ฅผ String์œผ๋กœ ๋ณ€๊ฒฝ ( + Locale ์ •๋ณด ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
  • T Parse(String text, Locale locale) : String์„ Object๋กœ ๋ณ€๊ฒฝ ( + Loclae ์ •๋ณด ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

 

์ด ํฌ๋งทํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด print๋ฉ”์†Œ๋“œ๋กœ ์ˆซ์ž(Object) 1000์„ (String)"1,000"์œผ๋กœ ๋ณ€๊ฒฝ.

parse๋ฉ”์†Œ๋“œ๋กœ 1000์„ (String)"1,000"์„ ์ˆซ์ž(Object) 1000์œผ๋กœ ๋ณ€๊ฒฝํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Slf4j
public class MyNumberFormatter implements Formatter<Number> {


    // parse : String to Object with formatting
    @Override
    public Number parse(String text, Locale locale) throws ParseException {
        log.info("text : {} , Locale : {}",text, locale);

        // "1,000" -> 1000
        return NumberFormat.getInstance(locale).parse(text);
    }

    // print : Object To String with formatting
    @Override
    public String print(Number object, Locale locale) {
        log.info("object = {} , locale = {}", object, locale);

        // 1000 -> "1,000"
        return NumberFormat.getInstance(locale).format(object);
    }
}

print ๋ฉ”์†Œ๋“œ : 1000->"1,000"

  • ์ˆซ์ž ์ค‘๊ฐ„์˜ ์‰ผํ‘œ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” NumberFormat ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • NumberFormat์€ locale์ •๋ณด๋ฅผ ํ†ตํ•ด format ๋ฉ”์†Œ๋“œ๋กœ ์‰ผํ‘œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  Number ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

parse ๋ฉ”์†Œ๋“œ : "1,000"->1000

  • ์ˆซ์ž ์ค‘๊ฐ„์˜ ์‰ผํ‘œ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” NumberFormat ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • NumberFormat์€ locale์ •๋ณด๋ฅผ ํ†ตํ•ด parse ๋ฉ”์†Œ๋“œ๋กœ ์‰ผํ‘œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Number ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.
ConversionService์— ํฌ๋งทํ„ฐ ๋“ฑ๋ก
์ปจ๋ฒ„ํ„ฐ๋ฅผ DefaultConversionService์— ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด,
ํฌ๋งทํ„ฐ๋Š” DefaultFormattingConversionService์— ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํฌ๋งทํ„ฐ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
์ปจ๋ฒ„ํ„ฐ์™€ ๋™์ผํ•˜๊ฒŒ WebMvcConfigurer ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์— addFormatters ๋ฉ”์†Œ๋“œ์— ๋“ฑ๋ก
@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());
    }

}

์—ฌ๊ธฐ์„œ ์ด์ „์— ๋งŒ๋“ค์—ˆ๋˜ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌํ•œ ์ด์œ ๋Š” ์ฃผ์„์ฒ˜๋ฆฌํ•œ Converter๋„ ์ˆซ์ž->๋ฌธ์ž, ๋ฌธ์ž->์ˆซ์ž๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜์˜ ๊ธฐ๋Šฅ์ด ๊ฒน์นฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ด ๊ฒน์น ๊ฒฝ์šฐ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋” ๋†’์Šต๋‹ˆ๋‹ค.

 

์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ํฌ๋งทํ„ฐ by Annotation

์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์›ํ•˜๋Š” ํ˜•์‹์„ ์ง€์ •ํ•ด์„œ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ์œ ์šฉํ•œ ํฌ๋งทํ„ฐ ๋‘๊ฐ€์ง€๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

@NumberFormat: ์ˆซ์ž ๊ด€๋ จ ํ˜•์‹ ์ง€์ • ํฌ๋งทํ„ฐ

@DateTimeFormat: ๋‚ ์งœ ๊ด€๋ จ ํ˜•์‹ ์ง€์ • ํฌ๋งทํ„ฐ

 

์–ด๋…ธํ…Œ์ด์…˜์— ํŒจํ„ด์„ ์ง€์ •ํ•ด ์›ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ํฌ๋งทํŒ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime localDateTime;
}
@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";
}

 

ConversionSerice๋Š” @RequestParam , @ModelAttribute , @PathVariable , ๋ทฐ ํ…œํ”Œ๋ฆฟ ๋“ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์˜ํ•  ์  : HttpMessageConverter(@RequestBody, @ResponseBody) ์—๋Š” ConversionService๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

HttpMessageConverter์˜ JSON ๊ฒฐ๊ณผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์ˆซ์ž๋‚˜ ๋‚ ์งœ ํฌ๋งท์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์œผ๋ฉด JackSon ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์„ค์ •์„ ์ฐพ์•„๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

 

<์ฐธ๊ณ  ์ž๋ฃŒ>

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

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard

 

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ