스프링 MVC 2 (4)

Seung·2023년 2월 18일
0
post-thumbnail

스프링 타입 컨버터

  • 스프링은 자동으로 타입 변환 적용을 해준다
    1. 스프링 MVC 요청 파라미터
    • @RequestParam, @ModelAttribute, @PathVariable
    1. @Value 등으로 YML 정보 읽기
    2. XML에 넣은 스프링 빈 정보를 반환
    3. 뷰를 렌더링 할때

타입 컨버터 - Converter

  • 타입 컨버터는 동일한 이름의 인터페이스가 많으니 해당 인터페이스 사용 'org.springframework.core.convert.convert.Converter'
  • 타입 컨버터 인터페이스
    public interface Converter<S, T>{
    	T convert(S source);
    }
  • 타입 컨버터 사용 예시 (String -> Integer)
    public class StringToIntegerConverter implements Converter<String , Integer>{
    	@Oerride
    	public Integer convert(String source){
       		return Integer.valueOf(source);
       }
    }

컨버전 서비스 - ConversionService

  • 타입 컨버터를 하나하나 사용시에는 개발자가 직접 컨버팅 하는 것과 큰 차이가 없다. 타입 컨버터를 등록하고 관리하면서 편리하게 변환 기능을 제공하는 역할

  • ConversionService 인터페이스

    public interface ConversionService {
    	boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);
      	boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
    
    	<T> T convert(@Nullable Object source, Class<T> targetType);
      	Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
      
    }
  • ConversionService Test

    @Test
    void conversrionSeriveTest(){
    	//DefaultConversionService는  컨버전서비스를 구현함, 추가로 컨버터 등록기능 보유
    	DefaultConversionService conversionService = new DefaultConversionService();
      
      //만든 타입 컨버터 등록
      convsersionService.addConverter(new StringToIntegerConverter());
      
      //사용 ("10"이라는 String을 Integer로 변경
      Integer result = conversionService.convert("10",Integer.class);
      
    }
    ##등록과 사용분리 ##
    컨버터를 등록할 떄는 타입 컨버터를 명확하게 알아야 하지만, 사용시에는
    해당 타입컨버터를 몰라도 사용이 가능하다.
    

스프링에 Converter 적용

  • WebConfig - 컨버터 등록
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    	
      @Override
      public void addFormatters(FormatterRegistry registry){
      	registry.addConverter(new StringToIntegerConverter());
      }
    }
    #######
    스프링은 내부에서 ConversionService를 제공한다.
    우리는 추가적으로 컨버터를 추가시에 WebMvcConfigurer가 제공하는 
    addFormatters()를 사용해서 추가하면 된다.
    추가를 완료하면 스프링은 내부에서 ConversionService에 등록한다.

포맷터 - Formatter

  • Converter는 입력과 출력 타입에 제한이 없는 범용 타입변환 기능을 제공하지만, 포맷터는 문자에 특화하여 예를 들면 Integer <-> String 변환시에
    1000 <-> "10,000" 특별한 형태의 문자로 출력하거나 사용시에 더욱 특화된 방법이다.

  • Converter vs Formatter

    • Converter : 범용(객체->객체)
    • Formatter : 문자에 특화 (객체->문자, 문자->객체) + Locale(현지화)
      Converter의 특별한 버전
    • Locale : 날짜,숫자의 표현방법은 현지화 정보가 사용될 수가 있음.
  • Formatter 인터페이스

    public interface Printer<T> {
    	String print(T object, Locale locale);
    }
    
    public interface Parser<T> {
    	T parse(String text, Locale locale) throws ParseException;
    }
    
    public interface Formatter<T> extends Printer<T>, Parser<T> {
    }
  • Formatter 사용 ("1,000" 처럼 중간의 쉼표넣기)

    public class MyNumberFormatter implements Formatter<Number>{
    	@Override
        public Number parse(String text, Locale locale) throws ParseException {
            NumberFormat format = NumberFormat.getInstance(locale);
            return format.parse(text);
        }
      
     	@Override
        public String print(Number object, Locale locale){
            return NumberFormat.getInstance(locale).format(object);
        }
    
    }
    #########
    자바가 제공해주는 NumberFormat 객체를 사용하여 Locale 정보를 활용하여 나라별 다른 숫자 포맷을 만들어준다.
    parse()는 문자 -> 숫자 변환
    print()는 객체 -> 문자 변환
    
  • MyNumberFormatter Test

    MyNumberFormatter formatter = new MyNumberFormatter();
    
    @Test
    void parse() throws ParseException {
    	Number result = formatter.parse("1,000", Locale.KOREA):
        assertThat(result).isEqualTo(1000L);
    }
    
    @Test
    void print(){
    	String result = formatter.print(1000, Locale.KOREA):
        assertThat(result).isEqualTo("1,000");
    }
  • WebConfig - 포맷터 등록

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    	
      @Override
      public void addFormatters(FormatterRegistry registry){
      	//컨버터등록
      	registry.addConverter(new StringToIntegerConverter());
          
        //포맷터 등록
        registry.addFormatter(new MyNumberFormatter());
      }
    }
    #######
    컨버전 서비스는 컨버터만 등록할 수 있고, 포맷터는 등록할 수는 없다.
    하지만 포맷터는 특별한 컨버터일 뿐이다.
    포맷터를 지원하는 컨버전 서비스를 사용하면 컨버전 서비스에 포맷터를 추가가 가능하다.
    내부 어댑터 패턴을 사용해서 포맷터가 컨버터럼 동작하도록 지원한다.
    

스프링이 제공하는 기본 포맷터

  • @NumberFormat
    숫자 관련 형식 지정 포맷터 사용
  • @DateTimeFormat
    날짜관련 형식 지정 포맷터사용
    public class Form {
    	
       @NumberFormat(pattern = "###,###")
       private Integer number;
       
       @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
       private LocalDateTime localDateTime;
    }
profile
한번 해봅시다.

0개의 댓글