컨버터
문자를 숫자로 변환하거나, 반대로 숫자를 문자로 변환해야 하는 것 처럼 애플리케이션을 개발하다 보면 타입을 변환해야 하는 경우가 상당히 많다.
이럴 때 컨버터를 사용해서 코드를 줄일 수 있다.
또한 스프링에서 @RequestParam, @ModelAttribute, @PathVariable과 @Value 등을 사용할때 String이 아닌 다른 타입으로 받을 수 있는 이유 또한 이 컨버터 덕분이다
스프링에서는 확장 가능한 컨버터 인터페이스를 제공하기 때문에 이를 구현해서 등록해주면 된다.
org.springframework.core.convert.Converter 인터페이스
이 인터페이스는 제네릭을 사용하고 있다. S->T
컨버전 서비스 - ConversionService
Converter인터페이스만 구현해서 필요한 컨버터 하나하나를 생성 또는 주입 받아서 사용하는 것은 매우 불편하다.
스프링은 개별 컨버터를 모아두고 그것들을 묶어서 편리하게 사용할 수 있는 클래스 또한 제공한다 그것이 바로 ConversionService이다.
- DefaultConversionService
- 밑의 ConversionService와 ConverterRegistry 인터페이스를 구현
- ConversionService
- 컨버터 사용에 초점
- ConverterRegistry
- 컨버터 등록에 초점
컨버터를 등록할 때는 컨버터 타입을 명확하게 알아야 하지만, 사용할 때는 몰라도 된다. 이렇게 분리함으로써 ISP원칙을 지킬 수 있게 된다.
스프링은 내부에서 ConversionService 를 사용해서 타입을 변환한다. 예를 들어서 앞서 살펴본 @RequestParam 같은 곳에서 이 기능을 사용해서 타입을 변환한다.
스프링에 사용자 정의 Converter 적용하기
우선 WebConfig에 컨버터를 등록해야한다.
@Configuration
public class WebConfig implemnets WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToIntegerConverter());
registry.addConverter(new IntegerToStringConverter());
registry.addConverter(new StringToIpPortConverter());
registry.addConverter(new IpPortToStringConverter());
}
}
위와 같이 등록해두면 컨트롤러 내부 코드 실행 전 컨버터가 작동하는 것을 컨버터에 로그를 찍어 확인할 수 있다.
처리 과정
@RequestParam 은 @RequestParam 을 처리하는 ArgumentResolver 인 RequestParamMethodArgumentResolver 에서 ConversionService 를 사용해서 타입을 변환한다. 부모 클래스와 다양한 외부 클래스를 호출하는 등 복잡한 내부 과정을 거치기 때문에 대략 이렇게 처리되는 것으로 이해해도 충분하다. 만약 더 깊이있게 확인하고 싶으면 IpPortConverter 에 디버그 브레이크 포인트를 걸어서 확인해보자.
타임리프에 컨버터 적용하기
<li>${number}: <span th:text="${number}" ></span></li>
<li>${{number}}: <span th:text="${{number}}" ></span></li>
<li>${ipPort}: <span th:text="${ipPort}" ></span></li>
<li>${{ipPort}}: <span th:text="${{ipPort}}" ></span></li>
- 실행 결과
- •${number}: 10000
- •${{number}}: 10000
- •${ipPort}: hello.typeconverter.type.IpPort@59cb0946
- •${{ipPort}}: 127.0.0.1:808
타임리프는 ${{...}} 를 사용하면 자동으로 컨버전 서비스를 사용해서 변환된 결과를 출력해준다. 물론 스프링과 통
합 되어서 스프링이 제공하는 컨버전 서비스를 사용하므로, 우리가 등록한 컨버터들을 사용할 수 있다.
- 변수 표현식 : ${...}
- 컨버전 서비스 적용 : ${{...}}
<form th:object="${form}" th:method="post">
th:field <input type="text" th:field="*{ipPort}"><br/>
th:value <input type="text" th:value="*{ipPort}">(보여주기 용도)<br/>
<input type="submit"/>
</form>
form 태그의 th:field 같은 경우 자동으로 컨버전 서비스도 함께 적용된다. (th:value는 적용안함)
- GET /converter/edit
- th:field 가 자동으로 컨버전 서비스를 적용해주어서${{ipPort}} 처럼 적용이 되었다. 따라서
- IpPort -> String 으로 변환된다.
- POST /converter/edit
- @ModelAttribute 를 사용해서 String -> IpPort 로 변환된다.
'Spring' 카테고리의 다른 글
[Spring] 파일 업로드 (0) | 2024.07.09 |
---|---|
[Spring] 포맷터 (Formatter) (0) | 2024.07.06 |
[Spring] Exception (예외) - ControllerAdvice (0) | 2024.06.28 |
[Spring] Exception (예외) - ExceptionHandler (0) | 2024.06.27 |
[Spring] 스프링 시큐리티(Spring Security) (0) | 2024.06.06 |