Converter

전현진·2025년 4월 15일

Spring

목록 보기
10/14

TypeConverter


타입 변환

Spring에서 객체의 타입을 서로 변환하는 데 사용되는 인터페이스로 Spring의 데이터 바인딩 과정에서 문자열을 특정 객체로 변환하거나 하나의 객체 타입을 다른 타입으로 변환할 때 사용한다.

  • 문자열을 숫자로
    • HttpServletRequest
@Slf4j
@RestController
public class TypeConverterController {

    @GetMapping("/param")
    public void param(HttpServletRequest request) {

        // 조회시 : String
        String stringExample = request.getParameter("example");

        // Integer로 Type 변환
        Integer integerExample = Integer.valueOf(stringExample);
        log.info("integerExample = {}", integerExample);

    }


}
  1. 요청 파라미터는 문자열로 처리된다.
  2. 다른 타입으로 변환해서 사용하고자 한다면 위와같이 검증 및 변환하는 과정이 필요하다.
  • @RequestParam
@GetMapping("/v2/param")
public void paramV2(@RequestParam Integer example) {
		// Integer 타입으로 바인딩
    log.info("example = {}", example);
}

추가적인 변환 작업을 거치지 않고 Integer 타입으로 바인딩된다.

  • 결론
    1. 요청 파라미터로 전달하는 10 값은 실제로는 문자열(String) 10이다.
    2. @RequestParam을 사용하면 문자 10을 Integer 타입의 숫자 10으로 변환된다.
    3. @ModelAttribute, @PathVariable 에서도 타입 변환을 확인할 수 있다.
    - Spring 내부에서 누군가가 타입을 자동으로 변환한다.

Converter Interface

Spring에서 특정 타입을 다른 타입으로 변환할 때 사용하는 인터페이스로 타입 변환 로직을 캡슐화하여 코드의 재사용성을 높이고 다양한 곳에서 타입 변환이 일관되게 수행되도록 돕는다.

  • 새로운 타입의 변환
    • localhost:8080/type-converter?person=wonuk:120
    • 입력받은 문자열 데이터를 Person 객체로 변환
public class Person {
		private String name;
		private String age;
}

wonuk:120 → TypeConverter → name: wonuk , age : 10

  • Converter Interface
    • Spring이 제공하는 인터페이스
      • implements하여 Converter로 등록하면 된다.
    • Converter는 모든 타입(T)에 적용할 수 있다.
    • 개발자가 새로운 Type을 만들어서 사용할 수 있도록 만든다.
      • 변환하고자 하는 타입에 맞춰서 Type Converter를 구현하고 등록하면 된다.






Converter


Converter 구현

데이터 유형 간 변환을 담당하는 메커니즘, 주로 웹 요청 파라미터를 Java 객체로 변환하거나 그 반대로 변환할 때 사용되며 커스텀 변환 로직을 정의할 수 있다.

  • 주의점
    - org.springframework.core.convert.converter
    - Spring의 Converter와 같은 이름을 가진 Interface가 많으니 주의해야 한다.

  • TypeConverter 사용

    • 구현은 단순하게 직접 메서드를 구현하여 모듈화 하면된다.
    • TypeConverter 를 생성하여 직접 사용하면 컨트롤러에서 변환하는 방식과 큰 차이가 없다.
PersonToStringConverter converter = new PersonToStringConverter();
String source = "wonuk:1200";
converter.convert(source);
  • Converter를 편리하게 등록하고 사용할 수 있도록 만들어주는 기능이 필요하다.
  • Spring은 String, Integer, Enum등 자주 사용되는 타입에 대한 컨버터를 제공하고 사용할 수 있도록 등록되어 있다.

Spring의 다양한 Converter

Spring에서 제공하는 다양한 Converter 인터페이스가 존재하며 이들은 Spring의 데이터 바인딩, 요청/응답 처리, 속성 값 주입 등에 사용되고 ConversionService를 통해 등록 및 관리된다.

  1. Converter
    • 기본적인 변환을 담당하는 인터페이스
    • 단일 타입에서 단일 타입으로 변환할 때 사용한다.
      • Converter<Source, Type>
  2. ConverterFactory
    • 클래스 계층 구조가 복잡한 경우 사용
    • 기본 타입과 다양한 서브 타입 간의 변환을 지원한다.
  3. GenericConverter
    • 다양한 타입 간의 유연한 변환을 지원한다.
    • 복잡한 타입 변환 로직을 구현할 때 유리하다.
  4. ConditionalGenericConverter
    • GenericConverter 의 확장형으로 특정 조건에서만 타입 변환을 수행한다.
    • 추가적으로 matches() 를 통해 변환 가능 여부를 판단할 수 있다.






ConversionService

Spring은 Converter를 모아서 편리하게 관리하고 사용할 수 있게 해주는 기능을 제공한다. 이것이 Conversion Service 이다.

  • ConversionService 인터페이스
  1. canConvert()
    • Convert 가능 여부를 확인하는 기능
  2. convert()
    • 실제 변환하는 기능

DefaultConversionService

Spring의 표준 ConversionService로 기본 제공 Converter와 확장 가능성을 통해 다양한 타입 변환을 유연하게 처리할 수 있도록 지원한다.

  • DefaultConversionService
    • ConversionService를 구현한 구현체
      • ConvertRegistry에 다양한 Converter를 등록한다.
  • ConverterRegistry
    • Converter를 등록하고 관리하는 기능을 제공한다.
  • 코드 예시
import static org.assertj.core.api.Assertions.*;

public class ConversionServiceTest {

    @Test
    void defaultConversionService() {
        // given
        DefaultConversionService dcs = new DefaultConversionService();
        dcs.addConverter(new StringToPersonConverter());
        Person wonuk = new Person("wonuk", 100);
        
				// when
        Person stringToPerson = dcs.convert("wonuk:1200", Person.class);
        
				// then
        assertThat(stringToPerson.getName()).isEqualTo(wonuk.getName());
        assertThat(stringToPerson.getAge()).isEqualTo(wonuk.getAge());
    }

}
  • 컨버터를 사용할 때는 종류를 몰라도된다.
  • 컨버터는 ConversionService 내부에서 숨겨진채 제공된다.
    • 반환 타입, 파라미터 타입, 제네릭 등으로 ConversionService가 컨버터를 찾는다.
  • 즉, 클라이언트는 ConversionService 인터페이스만 의존하면 된다.
    • 컨버터 등록과 사용의 분리

ISP(인터페이스 분리 원칙, Interface Segregation Principal)

클라이언트가 자신이 사용하지 않는 메서드에 의존하지 않도록 인터페이스를 분리하는 원칙

  • 인터페이스 분리 원칙(ISP)

    • DefaultConversionService
      1. ConversionRegistry : 컨버터 등록
      2. ConversionService **: **컨버터 사용
    • 인터페이스를 분리하면 컨버터를 사용하는 클라이언트는 필요한 메서드만 알면된다.
    • ConversionRegistry 가 변경되어도 ConversionService와 연관이 없다.
    • Spring은 내부적으로 위와같이 등록, 사용이 분리된 인터페이스들이 아주 많다.

Spring은 내부적으로 ConversionService를 사용해 타입을 변환한다. 대표적으로 @RequestParam , @PathVariable, @ModelAttribute 등이 해당 기능을 사용한다.

profile
안녕하세요

0개의 댓글