SPRING/스프링프레임워크 핵심개념

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

JUMP개발자 2021. 5. 23. 18:03

스프링 3.0 이후부터는 Converter와 Formatter를 이용해서 데이터 바인딩을 할 수 있다.

 

PropertyEditor의 단점

- Thread-safe하지 않음.

- String-Object 변환만 가능하다.

 

Converter

- S타입을 T타입으로 변환할 수 있는 일반적인 변환기 (여러 Type 변환가능)

- Thread-safe하기 때문에 Bean으로 등록하여 사용해도 됨.

-  ConverterRegistry에 등록하여 사용해야함.

 

일반적인 Spring에서는 아래와 같이 환결설정 파일(WebConfig)에 Converter를 등록하여 사용한다.

그러나 Spring Boot에서는 Converter를 bean으로 등록하여 사용할 수도 있다.

 

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new EventConverter.StringToEventConveter());
    }
}


public class EventConverter {

    // 스프링 부트의 경우에는 Formatter와 Converter 빈을 찾아 자동으로 등록해준다.
    // @Component
    public static class StringToEventConveter implements Converter<String, Event> {

        @Override
        public Event convert(String s) {
            return new Event(Integer.parseInt(s));
        }
    }
    // 스프링 부트의 경우에는 Formatter와 Converter 빈을 찾아 자동으로 등록해준다.
    //@Component
    public static class EventToStringConverter implements Converter<Event, String> {

        @Override
        public String convert(Event s) {
            return s.getId().toString();
        }
    }

}

public class Event {

    private Integer id;

    private String title;

    public Event(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
  
    @Override
    public String toString() {
        return "Event{" +
                "id=" + id +
                ", title='" + title + '\'' +
                '}';
    }
}
@RestController
public class EventController {
  
  @GetMapping("/event/{event}")
  public String getEvent(@PathVariable Event event) {
    System.out.println(event);
    return event.getId().toString();
  }
}

@RunWith(SpringRunner.class)
//@WebMvcTest는 web과 관련된 Bean만 등록하므로 그외의 Bean은 아래와 같이 Class를 등록해야함.
//@WebMvcTest({ EventConverter.StringToEventConveter.class, EventController.class})
// @WebMvcTest({ EventFormatter, EventController.class}) 
public class EventControllerTest {
 
    @Autowired
    MockMvc mockMvc;

    @Test
    public void getTest() throws Exception {
        mockMvc.perform(get("/event/1"))
                .andExpect((status().isOk()))
                .andExpect(content().string("1"));
    }
}

Formatter

 

- Formatter는 PropertyEditor와 같이 Object <-> String 간의 변환을 담당함.

- 다국화 기능을 제공함.

- FormatterRegistry에 등록하여 사용함.

@Component // Property-Editor와 달리 Thread-Safe함. (Bean등록하여 사용할 시)
public class EventFormatter implements Formatter<Event> {

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

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

EventFormatter를 Bean등록하지 않고 사용하려면 아래와 같이 환경설정 클래스에 추가하여 사용하면된다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new EventFormatter());
    }
}

 

ConversionService

- Convert와 Formatter의 Type 변환 작업은 DataBinder 대신에 Converter와 Formatter를 활용할 수 있게 해주는 ConversionService가 대신한다.

- 스프링 MVC, 빈 설정, SpEL에서 사용한다.