반응형
Converter 란?
- 객체를 다른 객체로 변환하는 기능
- 문자 <-> 숫자와 같은 변환들도 가능하고 객체끼리의 변환도 가능
Formatter 란?
- Formatter은 Converter와 비슷한 개념이지만 Converter은 객체 -> 객체에 사용된다면 Formatter은 객체 -> 문자, 문자 -> 객체에 특화되있음
- ex) 1000 -> "1,000" , LocalDateTime -> "yyyy-MM-dd HH:mm:ss" 같은 변환에 사용하면 유용
- 현지화 정보 (Locale)를 사용할 수 있음
Converter 예제
- URL 파라미터에 들어오는 값은 항상 String 타입인데, 이를 내가 만든 IpPort 타입으로 변환하는 Converter 예제
- 파라미터로 "127.0.0.1:8080"가 들어오면 ip = "127.0.0.1", port = 8080으로 변환하는 예제
IpPort
@Data
@AllArgsConstructor
public class IpPort {
private String ip;
private int port;
}
StringToIpPortConverter
- Converter<String, IpPort> : String을 IpPort 타입으로 convert 한다는 의미
public class StringToIpPortConverter implements Converter<String, IpPort> {
@Override
public IpPort convert(String source) {
String[] splitSource = source.split(":");
String ip = source.split(":")[0];
int port = Integer.valueOf(source.split(":")[1]);
return new IpPort(ip, port);
}
}
Controller
- 파라미터를 받을때 String 타입으로 받음
- StringToIpPortConverter 객체를 받아와 convert 메소드를 직접 사용해서 변환해도 되지만 conversionService를 이용해 변환할 수 있음
- conversionService를 이용하면 여러개의 converter을 한번에 add해놓고 사용할 때는 사용만 하면 됨
@ResponseBody
@GetMapping("/string-to-ip-port-v1")
public IpPort stringToIpPortV1(@RequestParam String str) {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToIpPortConverter());
IpPort ipPort = conversionService.convert(str, IpPort.class);
return ipPort;
}
결과
Converter 예제 2 - addFormatters 사용
- 위의 방식은 conversionService를 등록하고 매번 갖다 쓰는 방식
- 만약 이 Converter을 여러번 사용한다면 WebMvcConfigurer에 등록되어 있는 addFormatters를 통해 한 번에 등록하고 자동으로 변환하는 방식
WebConfig
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToIpPortConverter());
}
}
Controller
- URL 파라미터는 String 타입인데 여기서는 IpPort 타입으로 받음
- 위에서 등록한 StringToIpPortConverter가 이를 인식하고 String 타입의 입력을 자동으로 IpPort 타입으로 변환해줌
@ResponseBody
@GetMapping("/string-to-ip-port-v2")
public IpPort stringToIpPortV2(@RequestParam IpPort ipPort) {
return ipPort;
}
결과
Thymeleaf에서의 Converter 사용 예제
IpPortToStringConverter
- 위의 예제와 반대로 IpPort를 String으로 변환해주는 Converter
- 아래와 같이 작성 후 addFormatters에 같은 방식으로 등록해줘야 함
public class IpPortToStringConverter implements Converter<IpPort, String> {
@Override
public String convert(IpPort source) {
return source.getIp() + ":" + source.getPort();
}
}
Controller
- model에 IpPort 객체를 담아 전송
@GetMapping("/ip-port-to-string")
public String ipPortToString(Model model) {
model.addAttribute("ipPort", new IpPort("127.0.0.1", 8000));
return "converterPage";
}
converterPage.html
- Thymeleaf에서 기본적으로 모델 값을 받을때는 { } 를 사용
- 이 때, {{ }} 를 사용하면 객체에 맞는 Converter을 적용해서 출력
<ul>
<li>${ipPort} : <span th:text="${ipPort}"></span></li>
<li>${{ipPort}} : <span th:text="${{ipPort}}"></span></li>
</ul>
결과
- thymeleaf form에서는 th:field가 자동으로 converter을 적용해 줌
- 적용하기 싫으면 th:value 사용
Formatter 예제
MyNumberFormatter
- 1000 -> "1,000" 으로 변환해주는 기능
- 여기서 locale 는 현지화를 뜻하는데, 한국에서 실행하기 때문에 ko 이고, 한국 방식은 1000 -> "1,000"
public class MyNumberFormatter implements Formatter<Number> {
@Override
public Number parse(String text, Locale locale) throws ParseException {
// "1,000" -> 1000
NumberFormat format = NumberFormat.getInstance(locale);
return format.parse(text);
}
@Override
public String print(Number object, Locale locale) {
// 1000 -> "1,000"
NumberFormat instance = NumberFormat.getInstance(locale);
return instance.format(object);
}
}
WebConfig
- converter은 addConverter을 해준것과 비슷하게 formatter은 addFormatter을 해주면 됨
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new MyNumberFormatter());
}
}
Controller
- 화면으로 숫자 10000000을 넘겨줌 => 화면에선 10,000,000으로 출력
@GetMapping("/formatter-page")
public String formatterPage(Model model) {
model.addAttribute("number", 10000000);
return "formatterPage";
}
formatterPage.html
- converter와 같이 {{}}를 사용함으로써, formatting이 적용됨
- form에서도 마찬가지로 th:field가 자동으로 해주고, 적용하기 싫다면 th:value 사용
<ul>
<li>${number} : <span th:text="${number}"></span></li>
<li>${{number}} : <span th:text="${{number}}"></span></li>
</ul>
결과
특정 Object에서 변수에 어노테이션을 적용해 Formatter 적용 예제
Product
@Data
@AllArgsConstructor
public class Product {
private String name;
@NumberFormat(pattern = "###,###원")
private int price;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime registerDate;
}
Controller
@GetMapping("/formatter-page")
public String formatterPage(Model model) {
model.addAttribute("product", new Product("가방", 1000000, LocalDateTime.now()));
return "formatterPage";
}
formatterPage.html
- 상품명에는 Formatter 적용 X
- 가격과 등록일에 적용한 Formatter가 적용되기 위해 {{ }} 사용
<ul>
<li>상품명 : <span th:text="${product.name}"></span></li>
<li>가격 : <span th:text="${{product.price}}"></span></li>
<li>등록일 : <span th:text="${{product.registerDate}}"></span></li>
</ul>
결과
반응형
'Spring Boot > 문법 정리' 카테고리의 다른 글
[Spring Boot] JPA 관련 개념 정리 (0) | 2022.07.01 |
---|---|
[Spring Boot] 파일 업로드 (6) | 2022.06.29 |
[Spring Boot] Filter & Interceptor (0) | 2022.06.23 |
[Spring Boot] Validation, 에러메세지 설정방법 (2) | 2022.06.11 |
[Spring Boot] Thymeleaf - 메세지, 국제화 (0) | 2022.06.10 |