728x90

📝 데이터 바인딩 : 사용자가 입력한 문자열 값을 프로퍼티 타입에 맞춰 변환하여 할당하는 것

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/propertyeditors/package-summary.html

 

1. PropertyEditor ( 양뱡향 타입변환 / 스프링 3.0 이전 사용 )

🚨 PropertyEditor의 구현체는 빈으로 등록해서 사용하지 않는다. 

  • 쓰레드-세이프 하지 않음(상태 정보 저장 하고 있음)
  • Object와 String간의 변환만 할 수 있어, 사용 범위가 제한적 임 

특정 컨트롤러 내에서의 변환

User.java

private Date birth;        ## Date 타입 
private String[] hobby;    ## String[ ] 타입

 

Controller  

 @GetMapping("/user/{type}")
public String save( @PathVariable User user , Model m ){ 
    // 바인딩 되야할 객체 바로 뒤에 써야 하며,  
    // 컨트롤러에게 바인딩 결과를 주고 어떻게 처리할지 결정하게 한다.
} 

@InitBinder 
public void toDate( WebDataBinder binder ){ 
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); 
    binder.registerCustomEditor(Date.class , new CustomDateEditor(df, false) );
    // =============================================================================
    binder.registerCustomEditor(String[].class , new StringArrayPropertyEditor("#") ); 
    binder.registerCustomEditor(String[].class , "hobby" , new StringArrayPropertyEditor("#") );  //hobby에만
    // =============================================================================
    view 입력  >>>  테니스#수영#탁구 / 받기를 원하는 형태 [ 테니스 , 수영 , 탁구 ]  
    결과  >>> [ 테니스#수영#탁구 ]  이렇게 하나의 문자열로 들어오지만 
    WebDataBinder 로 해결할 수있다. [ 테니스, 수영, 탁구 ]
}

 

 


2. Formatter ( 양방향 타입변환 ) String -> 타입 / 타입 -> String

바인딩할 필드에 적용 : @NumberFormat  / @DateTimeFormat

사용 방법은 Convertet와 동일하다.

 

📝 Formatter의 특징 
- PropertyEditor 대체
- Object - String 간 변환을 담당하는 web 특화 인터페이스
- Spring이 제공하는 ConversionService 인터페이스를 통해 사용됨
- 값(상태 정보)을 저장하지 않으므로 thread-safe함
- 빈으로 등록해서 사용할 수 있음
- 문자열을 Locale에 따라 다국화 처리 하는 기능 제공 (Optional)

 ## InitBinder  대신 사용할수 있는 어노테이션 
 @DateTimeFormat(pattern="yyyy-MM-dd")    
 private Date birth;
 
 @NumberFormat(pattern="###,###")
 private BigDecimal salary;

 

Formatter는 제네릭으로 한 개의 인자만을 받는다.

왜냐하면 Object String간의 변환을 담당하기 때문에 다른 하나의 인자는 String으로 정해져 있기 때문이다.

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();
    }
}

 

Converter와 마찬가지로 WebMvcConfigurer 인터페이스를 구현한 클래스에 Formatter를 등록할 수 있다. 

@Configuration
public class WebConfig implements WebMvcConfigurer {

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

3. Converter ( 단방향 타입변환 ) 타입A => 타입B 

public class EventConverter { 

   public class StringToStringArrayConverter implements Converter<String , String[]>{ 
     public String[] convert (String source) {
        return source.split("#"); // String => String[]
     }
   }
   
   public static class StringToEventConverter implements Converter<String, Event> {
      public Event convert(String source){
         return new Event(Integer.parseInt(source));
      }
   } 
   
   public static class EventToStringConverter implements Converter<Event, String>{ 
      public String convert(Event source){
        return source.getId().toString();
      }
   }  
}

 📝 Converter의 특징
- Spring3 부터 추가됨 
- Spring이 제공하는 ConversionService 인터페이스를 통해 사용됨
- 값(상태 정보)을 저장하지 않으므로 thread-safe함
- 빈으로 등록해서 사용할 수 있음

 

1.Spring Web MVC만 사용하는 경우 - Web config에 등록 ( @Configuration )

위에서 작성한 Converter를 등록하려면 스프링MVC에서는 WebMvcConfigurer 인터페이스를 구현한 클래스를

작성해야 한다. WebMvcConfigurer 인터페이스의 addFormatters 메서드를 오버라이딩하여 Converter를 등록할 수 있다.

레지스트리에 등록한 Converter는 모든 Controller에 대해 동작하게 된다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

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

2. Spring Boot를 사용하는 경우 - Converter를 빈으로 등록( @Component )

public class EventConverter {
 
    @Component
    // Converter<Source, Target>
    public static class StringToEventConverter implements Converter<String, Event> {
  
        public Event convert(String s) {
            return new Event(Integer.parseInt(s));
        }
    }
 
    @Component
    public static class EventToStringConverter implements Converter<Event, String> {
  
        public String convert(Event event) {
            return event.getId().toString();
        }
    }
}

 

728x90

+ Recent posts