타입 컨버터
Converter
1
2
3
4
5
@GetMapping("/hello-v2")
public String helloV2(@RequestParam Integer data) {
System.out.println("data = " + data);
return "ok";
}
클라이언트의 요청 파라미터는 문자인데 위 코드에서 data 를 Integer 타입으로 받을 수 있는 이유는 스프링이 타입 컨버터를 이용해서 자동으로 타입을 변환해주기 때문이다.
스프링은 다음과 같은 경우에 타입 변환을 적용한다.
- 핸들러 메서드의 파라미터에 @RequestParam , @ModelAttribute , @PathVariable 가 적용되었을 때
- @Value 등으로 yml 정보를 읽어올 때
- xml 에 넣은 스프링 빈 정보를 변환할 때
- 뷰를 렌더링 할 때
스프링에는 다음과 같은 Converter 인터페이스가 정의되어 있다.
1
2
3
4
5
package org.springframework.core.convert.converter;
public interface Converter<S, T> {
T convert(S source);
}
스프링에는 위 인터페이스를 상속받아 구현한 수많은 컨버터가 자동으로 등록되어 있다.
만약 추가적인 타입 변환이 필요하다면 위 인터페이스를 상속받아 구현하고 WebMvcConfigurer
에 등록하면 된다. (수동으로 등록한 컨버터가 우선 순위를 가진다.)
등록된 컨버터는 핸들러 메서드를 호출하기 전 ArgumentResolver
내부에서 ConversionService
에 의해 호출된다.
Formatter
숫자 1000 을 문자 1,000 으로 뷰 템플릿에 적용하거나 문자 1,000 을 핸들러 메서드에서 숫자 1000 으로 전달받으려고 할 때 Formatter 를 사용하면 쉽게 해결할 수 있다.
스프링에는 다음과 같은 Formatter 인터페이스가 정의되어 있다.
Formatter
1
2
3
4
package org.springframework.format;
public interface Formatter<T> extends Printer<T>, Parser<T> {
}
Printer<T>
1
2
3
4
5
package org.springframework.format;
public interface Printer<T> {
String print(T object, Locale locale);
}
Parser<T>
1
2
3
4
5
package org.springframework.format;
public interface Parser<T> {
T parse(String text, Locale locale) throws ParseException;
}
스프링에는 위 인터페이스를 상속받아 구현한 포맷터가 자동으로 등록되어 있다.
만약 추가적인 포맷이 필요하다면 위 인터페이스를 상속받아 구현하고 WebMvcConfigurer
에 등록하면 된다.
수동으로 등록한 Formatter 가 Number to String / String to Number 일 때 수동으로 등록한 Integer to String / String to Integer 컨버터가 있다면 Formatter 가 적용되지 않을 수 있다.
숫자 1000 을 문자 1,000 으로 뷰 템플릿에 적용할 때는 디스패처 서블릿의 render() 함수 내부에서 ConversionService
에 의해 호출되고
문자 1,000 을 핸들러 메서드에서 숫자 1000 으로 받을 때는 핸들러 메서드를 호출하기 전 ArgumentResolver 내부에서 ConversionService
에 의해 호출된다.
숫자 혹은 날짜와 관련된 포맷이라면 스프링이 제공하는 @NumberFormat , @DateTimeFormat 어노테이션을 사용하는 것이 훨씬 편리하다.
1
2
3
4
5
6
7
8
@Data
static class Form {
@NumberFormat(pattern = "###,###")
private Integer number;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
}
메시지 컨버터(HttpMessageConverter) 에는 컨버전 서비스가 적용되지 않는다. 이 때는 HTTP 메시지 바디를 객체로 변환하거나 객체를 HTTP 메시지 바디로 변환하는 라이브러리가 제공하는 방식으로 포맷을 적용해야 한다.
Converter/Formatter - Thymeleaf
뷰 템플릿에 컨버전이 적용된 값을 출력하고 싶다면 컨버전 서비스 적용 표현식 ${{…}}
를 사용하면 된다. (th:field
를 사용해도 자동으로 컨버전 서비스를 적용한다.)