ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 데이터 바인딩 추상화 - propertyEditor, Converter, Formmater
    백기선(인프런 강의)/스프링 프레임워크 핵심 기술 2020. 3. 25. 12:38
    반응형

    propertyEditor

    org.springframework.validation.DataBinder
    java.beans.PropertyEditor

    https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/DataBinder.html

     

    WEB MVC에만 특화된 것이 아니라 여러 곳에서 쓰이는 스프링 핵심 기술

    기술적인 관점

    • 프로퍼티 값을 타겟 객체에 설정하는 기능

    사용자 관점

    • 사용자 입력값을 애플리케이션 도메인 모델에 동적으로 변환해 넣어주는 기능.
      • 입력값은 대부분 “문자열”인데, 그 값을 객체가 가지고 있는 int, long, Boolean, Date 등 심지어 Event, Book 같은 도메인 타입으로도 변환해서 넣어주는 기능.

    PropertyEditor 

    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 + "]";
    	}
    
    }
    public class EventEditor extends PropertyEditorSupport{
    	@Override
        public String getAsText() {
            Event event = (Event)getValue();
            return event.getId().toString();
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            setValue(new Event(Integer.parseInt(text)));
        }
    }

     

    • 스프링 3.0 이전까지 DataBinder가 변환 작업 사용하던 인터페이스 
    • getValuePropertyEditorSupport가 받은 객체를 가져올 수 있다.
    • getValue와 setValue는 객체를 공유하고 있으며 PropertyEditor가 가지고 있는 값이다. 
    • 서로 다른 쓰레드에 공유를 한다.(쓰레드-세이프 하지 않음)
    • Bean으로 등록해서 쓰지 말아야 한다.
      • ObjectString 간의 변환만 할 수 있어, 사용 범위가 제한적 임. 
    • ObjectString의 관계
    @RestController
    public class EventController {
    
        @InitBinder
        public void init(WebDataBinder webDataBinder){
            webDataBinder.registerCustomEditor(Event.class, new EventEditor());
        }
    
        @GetMapping("/event/{event}")
        public String getEvent(@PathVariable Event event){
            System.out.println(event);
            return event.getId().toString();
        }
    }

     


    Converter, Formatter

    Converter 

    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();
            }
        }
    }
    • S (Source) 타입을 T (Target) 타입으로 변환할 수 있는 매우 일반적인 변환기. 
    • 상태 정보 없음 == Stateless == 쓰레드세이프 
      • Bean으로 등록 가능

     

    @Configuration
    public class WebConfig implements WebMvcConfigurer{
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new EventConverter.StringToEventConverter());
        }
    }
    • Srping MVC만 사용할 경우 ConverterRegistry에 등록해서 사용 

     

    Formatter

    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();
        }
    }
    • PropertyEditor 대체제
    • ObjectString 간의 변환을 담당
    • 문자열을 Locale에 따라 다국화하는 기능도 제공(optional)
    @Configuration
    public class WebConfig implements WebMvcConfigurer{
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addFormatter(new EventFormatter());
        }
    }
    • FormatterRegistry 에 등록해서 사용

     

    Converter, Formatter Bean 등록방법

    public class EventConverter {
        @Component
        public static class StringToEventConverter implements Converter<String, Event>{
            @Override
            public Event convert(String source) {
                return new Event(Integer.parseInt(source));
            }
        }
    }
    @Component
    public class EventFormatter implements Formatter<Event> {
        @Override
        public Event parse(String text, Locale locale) throws ParseException {
            return new Event(Integer.parseInt(text));
        }
    }
    • @Component를 사용하여 Bean등록

     

    ConversionService

    • 실제 변환 작업은 이 인터페이스를 통해서 쓰레드-세이프하게 사용할 수 있음. 
    • 스프링 스프링 MVC, 빈 (value) 설정, SpEL에서 사용한다. 
    • DefaultFormattingConversionService
      • FormatterRegistry 
      • ConversionService 
      • 여러 기본 컴버터와 포매터 등록 해 줌. 

    ConversionService 조회(Spring boot)

    @Component
    public class AppRunner implements ApplicationRunner{
    
        @Autowired
        ConversionService conversionService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println(conversionService);
        }
    }
    ConversionService converters =
    	@org.springframework.format.annotation.DateTimeFormat java.lang.Long -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@3b95a6db,@org.springframework.format.annotation.NumberFormat java.lang.Long -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@309cedb6
    	@org.springframework.format.annotation.DateTimeFormat java.time.LocalDate -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@36b9cb99,java.time.LocalDate -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@4130955c
    	@org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime -> 
    .....

     

    스프링 부트

    • 웹 애플리케이션인 경우에 DefaultFormattingConversionSerivce를 상속하여 만든
      WebConversionService를 빈으로 등록해 준다.
    •  Formatter와 Converter 빈을 찾아 자동으로 등록해 준다.

     

    반응형
Designed by Tistory.