728x90
- 문자를 숫자로 변환하거나, 반대로 숫자를 문자로 변환해야 하는 것처럼 애플리케이션을 개발하다 보면 타입을 변환해야 하는 경우가 상당히 많다
@GetMapping("/hello-v1")
public String helloV1(HttpServletRequest request){
String data = request.getParameter("data");//문자 타입 조회
Integer intValue = Integer.valueOf(data);//숫자 타입으로 변경
System.out.println("intValue = " + intValue);
return "ok";
}
- HTTP 요청 파라미터는 모두 문자로 처리된다
- 따라서 요청 파라미터를 자바에서 다른 타입으로 변환해서 사용하고 싶으면 숫자 타입으로 변환하는 과정을 거쳐야 한다.
@GetMapping("/hello-v2")
public String helloV2(@RequestParam Integer data){
System.out.println("data = " + data);
return "ok";
}
- 스프링이 제공하는 @RequestParam 을 사용하면 이 문자 10을 Integer 타입의 숫자 10으로 편리하게 받을 수 있다.
- 이것은 스프링이 중간에서 타입을 변환해주었기 때문이다.
- 이러한 예는 @ModelAttribute , @PathVariable에서도 확인할 수 있다.
- 스프링의 타입 변환 적용 예
- 스프링 MVC 요청 파라미터
- @RequestParam , @ModelAttribute , @PathVariable
- @Value 등으로 YML 정보 읽기
- XML에 넣은 스프링 빈 정보를 변환
- 뷰를 렌더링 할 때
- 스프링 MVC 요청 파라미터
컨버터 인터페이스
public interface Converter<S, T> {
T convert(S source);
}
- 스프링은 확장 가능한 컨버터 인터페이스를 제공한다.
- 개발자는 스프링에 추가적인 타입 변환이 필요하면 이 컨버터 인터페이스를 구현해서 등록하면 된다.
- 이 컨버터 인터페이스는 모든 타입에 적용할 수 있다. 필요하면 X -> Y 타입으로 변환하는 컨버터 인터페이스를 만들고, 또 Y -> X 타입으로 변환하는 컨버터 인터페이스를 만들어서 등록하면 된다.
- 예를 들어서 문자로 "true" 가 오면 Boolean 타입으로 받고 싶으면 String -> Boolean 타입으로 변환되도록 컨버터 인터페이스를 만들어서 등록하고, 반대로 적용하고 싶으면 Boolean -> String 타입으로 변환되도록 컨버터를 추가로 만들어서 등록하면 된다
- 참고
- 과거에는 PropertyEditor 라는 것으로 타입을 변환했다. PropertyEditor는 동시성 문제가 있어서 타입을 변환할 때마다 객체를 계속 생성해야 하는 단점이 있다. 지금은 Converter의 등장으로 해당 문제들이 해결되었고, 기능 확장이 필요하면 Converter를 사용하면 된다
타입 컨버터 - Converter
문자 -> 숫자
@Slf4j
public class StringToIntegerConverter implements Converter<String, Integer> {
@Override
public Integer convert(String source) {
log.info("convert source={}", source);
return Integer.valueOf(source);
}
}
숫자 -> 문자
@Slf4j
public class IntegerToStringConverter implements Converter<Integer, String> {
@Override
public String convert(Integer source) {
log.info("convert source={}", source);
return String.valueOf(source);
}
}
클래스 생성
@Getter
@EqualsAndHashCode
public class IpPort {
private String ip;
private int port;
public IpPort(String ip, int port){
this.ip = ip;
this.port = port;
}
}
클래스 -> 문자
@Slf4j
public class IpPortToStringConverter implements Converter<IpPort, String> {
@Override
public String convert(IpPort source) {
log.info("converter source={}", source);
//IpPort 객체 -> "127.0.0.1:8080"
return source.getIp() + ":" + source.getPort();
}
}
문자 -> 클래스
@Slf4j
public class StringToIpPortConverter implements Converter<String, IpPort> {
@Override
public IpPort convert(String source) {
log.info("convert source={}", source);
//"127.0.0.1:8080" -> IpPort 객체
String[] split = source.split(":");
String ip = split[0];
int port = Integer.parseInt(split[1]);
return new IpPort(ip, port);
}
}
Test
public class ConverterTest {
@Test
public void stringToInteger(){
StringToIntegerConverter converter = new StringToIntegerConverter();
Integer result = converter.convert("10");
assertThat(result).isEqualTo(10);
}
@Test
public void IntegerToString(){
IntegerToStringConverter converter = new IntegerToStringConverter();
String result = converter.convert(10);
assertThat(result).isEqualTo("10");
}
@Test
public void StringToIpPort(){
IpPortToStringConverter converter = new IpPortToStringConverter();
IpPort source = new IpPort("127.0.0.1", 8080);
String result = converter.convert(source);
assertThat(result).isEqualTo("127.0.0.1:8080");
}
@Test
public void ipPortToString(){
StringToIpPortConverter converter = new StringToIpPortConverter();
String source = "127.0.0.1:8080";
IpPort result = converter.convert(source);
assertThat(result).isEqualTo(new IpPort("127.0.0.1", 8080));
}
}
- TypeConverter를 직접 사용하고, 테스트를 진행 해보았다.
- 타입 컨버터 인터페이스가 단순해서 이해하기 어렵지 않을 것이다.
- 그런데 이렇게 타입 컨버터를 하나하나 직접 사용하면, 개발자가 직접 컨버팅 하는 것과 큰 차이가 없다.
- 타입 컨버터를 등록하고 관리하면서 편리하게 변환 기능을 제공하는 역할을 하는 무언가가 필요하다
- 참고
- 스프링은 용도에 따라 다양한 방식의 타입 컨버터를 제공한다.
- Converter -> 기본 타입 컨버터
- ConverterFactory -> 전체 클래스 계층 구조가 필요할 때
- GenericConverter -> 정교한 구현, 대상 필드의 애노테이션 정보 사용 가능
- ConditionalGenericConverter -> 특정 조건이 참인 경우에만 실행
728x90
'스프링 MVC 2편(백엔드 웹 개발 활용 기술)' 카테고리의 다른 글
| Ch10. 스프링 타입 컨버터 소개 - 스프링에 Converter 적용하기 (0) | 2022.03.22 |
|---|---|
| Ch10. 스프링 타입 컨버터 소개 - 컨버전 서비스(ConversionService) (0) | 2022.03.22 |
| Ch09. API 예외 처리 - @ControllerAdvice (0) | 2022.03.21 |
| Ch09. API 예외 처리 - 스프링이 제공하는 ExceptionResolver (0) | 2022.03.21 |
| Ch09. API 예외 처리 - HandlerExceptionResolver (0) | 2022.03.21 |