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에서 사용한다.