본문 바로가기
Spring/Spring Core

Section 3. 데이터 바인딩 추상화: Converter와 Formatter

by kevinntech 2020. 10. 5.

해당 게시물은 백기선님의 스프링 프레임워크 핵심 기술 강좌를 정리한 내용 입니다.

 

 

Converter

 

- S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기.

 

- 상태 정보 없음 == Stateless == 쓰레드 세이프

 

- ConverterRegistry 에 등록해서 사용

 

Converter를 이용한 데이터 바인딩

 

1) Converter 구현

 

     Converter 인터페이스를 구현하는 클래스를 작성 합니다.

     Converter는 두 개의 제네릭 파라미터를 받습니다. 첫 번째는 source 타입, 두 번째는 target 타입이다.

     현재 예제의 경우 text를 Event로 변환해야 하므로 Converter<String, Event>만 구현하면 된다.

 

public class EventConverter {
    
    public static class StringToEventConverter implements Converter<String, Event>{
        @Override
        public Event convert(String source) {
            return new Event(Integer.parseInt(source));
        }
    }

    public static class EventToStringConverter implements Converter<Event, String>{
        @Override
        public String convert(Event source) {
            return source.getId().toString();
        }
    }
}

 

2) Spring Web MVC만 사용하는 경우, 컨버터 등록 

     스프링 MVC 자바 설정 파일(WebConfig)에서 addFormatters()를 오버라이딩한 다음, FormatterRegistry의 addConverter()로 
     컨버터를 등록한다.

 

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new EventConverter.StringToEventConverter());
    }
}


     FormatterRegistry에 등록한 Converter는 모든 Controller에 대해 동작하게 된다.
     해당 컨트롤러로 요청한 1은 StringToEventConverter에서 Event 타입으로 변환되어 컨트롤러의 getEvent()에서

     Event 타입으로  받을 수 있게 되는 것이다.

 

3) 테스트 코드 실행

 

 

Formatter 인터페이스

 

- Formatter는 PropertyEditor 대체재이며 Object와 String 간의 변환을 담당한다.

 

- 문자열을 Locale에 따른 다국어 기능을 제공한다. (optional)

 

- FormatterRegistry 에 등록해서 사용

 

- thread-safe 하므로 빈으로 등록해서 사용 할 수도 있다.

 

   @Component 
    public class EventFormatter implements Formatter<Event> {

   }

 

Formatter를 이용한 데이터 바인딩

 

  1) Formatter 구현

 

        Formatter 인터페이스를 구현한 클래스를 작성 합니다.

 

        Formatter는 한 개의 타입 매개변수에 해당 Formatter로 처리할 타입을 지정한다.

        그리고 parse()와 print() 메서드를 구현해야 한다.

 

        print() : 객체(Object)를 문자열(String)으로 변환한다.

        parse() : 문자열(String)을 객체(Object)로 변환한다.

 

public class EventFormatter implements Formatter<Event> {

    @Override
    public Event parse(String text, Locale locale) throws ParseException {
        return new Event(Integer.parseInt(text));
    }

    @Override
    public String print(Event object, Locale locale) {
        return object.getId().toString();
    }
}

 

2) Spring Web MVC만 사용하는 경우, Formatter 등록 

     스프링 웹 설정 파일(WebConfig)에서 FormatterRegistry에 addFormatter()를 이용하여 Formatter를 등록한다.

 

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new EventFormatter());
    }
}

 

ConversionService

 

PropertyEditor가 DataBinder를 통해 사용된다면 Converter와 Formatter는 ConversionService를 통해 사용된다.

 

FormatterRegistry의 addFormatter()로 등록한 Converter와 Formatter는 ConversionService에 등록되어 실제 변환 작업을 하게 된다.

 

Spring이 제공하는 여러가지 ConversionService 구현체 중 DefaultFormattingConversionService 가 자주 사용된다.

 

 

   위 그림과 같이  DefaultFormattingConversionService는 ConversionService와 FormatterRegistry, ConverterRegistry를 구현하여


   해당 인터페이스들의 기능을 포함한다.  또한 여러 기본 Converter와 Formatter가 등록되어 있다. 
  
   기본적으로 Converter를 레지스트리에 등록할때는 ConverterRegistry에, Formatter는 FormatterRegistry에 등록해서 사용하지만


   FormatterRegistry는 ConverterRegistry를 상속받고 있기 때문에 예제 코드에서와 같이 FormatterRegistry에 Converter를 등록할 수 있다. 

   그리고 ConversionService에 등록되어 있는 Converter, Formatter들을 확인하려면 ConversionService 참조변수를 출력해보면 된다.

 

스프링 부트에서의 Converter와 Formatter


 - 스프링 부트 웹 애플리케이션인 경우, DefaultFormattingConversionSerivce를 상속하여 만든 WebConversionService를 빈으로  
    등록해 준다. 

 

- 스프링 부트는 Formatter와 Converter 빈을 찾아 자동으로 ConversionService에 등록해 준다. 
   (먼저 Formatter와 Converter에 @Component를 붙여 빈으로 등록 되어 있어야 됨)

 

 

댓글