1. 컨버터란
숫자를 문자로 변환하거나, 문자를 숫자로 변환하는 것처럼 개발을 하다 보면 타입을 변환해야 하는 경우가 많다.
이러한 컨버터를 스프링은 편리하게 도와주고 있다. 예시를 보자.
@GetMapping("/converter-v1")
public String converterV1(HttpServletRequest request){
String data = request.getParameter("data");
//Integer로 직접 타입 변환
Integer integer = Integer.valueOf(data);
System.out.println("integer = " + integer);
return "sucess";
}
@GetMapping("/converter-v2")
public String converterV2(@RequestParam Integer data){
//스프링이 중간에서 타입을 변환해 줬기 때문에 가능
//data = java.lang.Integer
System.out.println("data = " + data.getClass().getName());
return "sucess";
}
위의 예제를 보면 쿼리스트링으로 받은 data 값은 default가 String 타입으로 되어있으므로 Integer로 타입을 변환하려면 Integer.valueOf(data)를 통해 변환해야 한다. 그렇기에 컨트롤러에서 HttpServletRequest를 통해서 받게 되면 적용해야 하는 모든 부분을 변환해줘야 하는 번거로움이 생긴다.
하지만 스프링이 제공하는 @RequestParam 을 사용하면 문자 타입을 Integer 타입으로 편리하게 받을 수 있다.
이것은 스프링이 중간에서 타입을 변환해주었기 때문이다.
그렇다면 스프링을 이용하는 개발자가 자신이 원하는 타입으로 변환하는 부분을 만들고 싶으면 어떡할까?
그렇다면 컨버터 인터페이스를 사용하면 된다.
2. 컨버터 인터페이스란
org.springframework.core.convert.converter 패키지에는 Converter라는 이름의 인터페이스가 있다.
public interface Converter<S, T> {
/**
* Convert the source object of type {@code S} to target type {@code T}.
* @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
* @return the converted object, which must be an instance of {@code T} (potentially {@code null})
* @throws IllegalArgumentException if the source cannot be converted to the desired target type
*/
@Nullable
T convert(S source);
Converter는 S타입을 T타입으로 변환할 수 있는 매우 일반적인 변환기
Converter<source, target>
- source는 바꾸기 전 데이터 타입
- target은 바꿀 데이터 타입
Converter는 source와 target을 설정해줘야 한다.
스프링은 확장 가능한 컨버터 인터페이스를 제공하는데 개발자는 스프링에 추가적인 타입 변환이 필요하면 이 컨버터 인터페이스를 구현해서 등록하면 된다.
이 컨버터 인터페이스는 모든 타입에 적용할 수 있다.
2-1. 컨버터 인터페이스 사용 예시
< String -> Integer 타입 변환 >
@Slf4j
public class StringToIntegerConverter implements Converter<String, Integer> {
@Override
public Integer convert(String source) {
log.info("StringToIntegerConverter source={}",source);
return Integer.valueOf(source);
}
}
< Integer -> String 타입 변환 >
@Slf4j
public class IntegerToStringConverter implements Converter<Integer, String> {
@Override
public String convert(Integer source) {
log.info("IntegerToStringConverter source : {}",source);
return String.valueOf(source);
}
}
<test>
class converterTest {
@Test
void Test(){
StringToIntegerConverter converter = new StringToIntegerConverter();
assertThat(100).isEqualTo(converter.convert("100"));//성공
}
@Test
void Test2(){
IntegerToStringConverter converter = new IntegerToStringConverter();
assertThat("100").isEqualTo(converter.convert(100));//성공
}
}
test코드에서 형 변환이 잘 되는지 확인 해 보면 문제없이 형변환이 되는 것을 볼 수 있다.
이렇게 하나하나 추가할 수는 있겠지만 만든 컨버터를 사용할 때 일일이 객체를 생성해야 하기 때문에 만들어진 컨버터들을 관리해주는 역할을 하는 무언가가 필요하다는 생각이 들것이다.
그 역할을 편리하게 도와주는 기능이 있는데 그것은 컨버전 서비스이다.
3. 컨버전 서비스
그래서 스프링은 개별 컨버터를 모아 두고 그것들을 묶어서 편리하게 사용할 수 있는 기능을 제공하는데,
이것이 바로 컨버전 서비스( ConversionService )이다.
3-1 컨버전 서비스 테스트
< 컨버전 서비스 test >
class converterTest {
@Test
void conversionService(){
//DefaultConversionService는 컨버터를 등록하는 기능을 제공
DefaultConversionService conversionService = new DefaultConversionService();
//컨버터 추가
conversionService.addConverter(new StringToIntegerConverter());
conversionService.addConverter(new IntegerToStringConverter());
assertThat(conversionService.convert("100", Integer.class)).isEqualTo(100);//성공
assertThat(conversionService.convert(100, String.class)).isEqualTo("100");//성공
}
[Test worker] INFO converter.StringToIntegerConverter - StringToIntegerConverter source = 100
[Test worker] INFO converter.IntegerToStringConverter - IntegerToStringConverter source : 100
DefaultConversionService는 ConversionService 인터페이스를 구현했는데, 추가로 컨버터를 등록하는 기능도 제공한다. 형변환을 테스트할 때 String에서 Integer로 형변환 시에 추가한 StringToIntegerConverter를 사용하는 것을 로그로 확인 할 수 있다.
이렇게 컨버전 서비스를 이용하면 편리하게 컨버터를 사용 및 관리할 수 있다.
3-2 컨버전 서비스 등록
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToIntegerConverter());
registry.addConverter(new IntegerToStringConverter());
}
}
스프링은 ConversionService 를 제공하는데 WebMvcConfigurer 가 제공하는 addFormatters() 를 사용해서 추가하고 싶은 컨버터를 등록하면 된다.
이렇게 하면 스프링은 내부에서 사용하는 ConversionService 에 컨버터를 추가해준다.
이렇게 등록을 해주게 되면 위의 3-1 컨버전 서비스 테스트와 마찬가지로 스프링 내부에서 String에서 Integer로 형변환 시에 추가한 StringToIntegerConverter 사용해서 형변환을 하게된다.
'SPRING' 카테고리의 다른 글
2. 파일 업로드 (Spring) (0) | 2021.08.19 |
---|---|
1. 파일 업로드 (Servlet) (0) | 2021.08.19 |
예외처리 - HandlerExceptionResolver (0) | 2021.08.07 |
Filter와 Interceptor ( 2. Interceptor ) - 로그인 관련 (0) | 2021.08.06 |
Filter와 Interceptor ( 1. Filter ) - 로그인 관련 (0) | 2021.08.05 |