스프링 타입 컨버터란?
HTTP 쿼리스트링을 통해 전해지는 모든것은 문자로 인식된다.
하지만 localhost:8080/test?itemId=10 처럼 쿼리스트링을 보냈을때, 컨트롤러에서는 Long itemId의 숫자 타입으로 입력받을 수 있다.
이처럼 형변환이 되려면 매개변수를 처리하는 과정에서 자동으로 호출되는 변환 기능이 있어야 한다.
이것이 스프링 타입 컨버터이다.
스프링 타입 컨버터의 아래의 어노테이션을 대상으로 사용 가능하다.
- @RequestParam
- @ModelAttribute
- @PathVariable
스프링 타입 컨버터 사용
스프링 타입 컨버터는 Converter라는 인터페이스를 구현해서 사용할 수 있다.
Converter<S,T> 형태에서 S는 입력값의 형태를, T에는 변환하길 원하는 형태를 의미한다.
구체적인 사용 예를 살펴보자
public class StringToIntegerConverter implements Converter<String,Integer> {
@Override
public Integer convert(String source) {
return Integer.valueOf(source);
}
}
Converter를 구현하는 클래스를 만든 후 제네릭으로 원하는 자료형들을 넣어주면 매개변수와 반환 타입이 설정된 convert 메서드를 오버라이딩 할 수 있다.
StringToIntegerConverter가 잘 작동하는지 테스트코드를 작성해보자
class StringToIntegerConverterTest {
@Test
void converterTest()
{
StringToIntegerConverter converter = new StringToIntegerConverter();
Integer result = converter.convert("10");
Assertions.assertThat(result).isEqualTo(10);
}
}
문자열 "10"을 convert의 인자로 전달한 후, 반환값이 숫자형의 10이랑 같은지 체크하는 테스트를 진행했다.
테스트 성공!
컨버터들을 관리해주는 ConversionService
우리는 상황에 따라 많은 컨버터를 만들 수 있다.
예를 들어,
- String을 열거형으로 변환해주는 컨버터
- String을 특정 객체로 변환해주는 컨버터
- Integer를 특정 객체로 변환해주는 컨버터
이 외에도 다양한 컨버터를 제작할 수 있고, 실제로 스프링에는 훨씬 다양한 컨버터들이 등록되어있다.
이때 모든 컨버터들을 관리해주고, 클라이언트가 원하는 자료형을 입력만 하면 알아서 컨버터를 찾아서 적용해주는 기능이 있다면 매우 편할 것이다,
이 역할을 하는 것이 ConversionService이다.
ConversionService의 사용법을 알아보자.
class StringToIntegerConverterTest {
@Test
void converterTest()
{
// 원하는 컨버터 생성
StringToIntegerConverter stringToIntegerconverter = new StringToIntegerConverter();
// conversionService 생성
DefaultConversionService conversionService = new DefaultConversionService();
// conversionService에 converter 등록
conversionService.addConverter(stringToIntegerconverter);
Integer result = conversionService.convert("10", Integer.class);
Assertions.assertThat(result).isEqualTo(10);
}
}
DefaultConversionService는 인터페이스인 ConversionService의 구현체이다.
convert 메서드에 입력값과 내가 원하는 반환 타입만 지정해주면 conversionService는 등록한 컨버터중에 해당 작업을 진행할 수 있는 컨버터를 자동으로 찾아준다.
💡 클라이언트는 서버측에서 어떤 컨버터를 등록했는지는 알 필요없이 convert 메서드를 사용하기만 하면 된다.
이제 우리는 ConversionService에 컨버터를 등록 후 형변환을 할 수 있게 됐다.
하지만 타입 컨버팅의 모든 경우의 수를 내가 다 구현하려면 너무 힘들 것이다.
스프링은 이미 수많은 타입 컨버터를 구현해놓았고, conversionService를 내장하고 있다.
정말 특별한 경우( ex> String을 입력 후 내가 만든 커스텀 객체로 변환할 때)를 제외하고는 스프링 내장 컨버터가 알아서 변환해준다.
그럼 특별한 경우에 어떻게 컨버터를 등록하는지 알아보자.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToIntegerConverter());
}
}
WebConfig 클래스를 만든 후 WebMvcConfigurer 인터페이스를 구현한다.
WebMvcConfigurer는 MVC와 관련된 각종 커스터마이징 및 설정을 가능하게 해준다.
이제 String이 컨트롤러로 들어오면 @RequestParam, @ModelAttribute, @PathVariable 에서 Integer형으로 받을 시, 내가 만든 컨버터가 동작한다!