본문 바로가기
Spring Boot/Core

데이터 바인딩 추상화

by Holy Moly 2022. 7. 26.

데이터 바인딩이란 ? 

 

기술적인 관점: 프로퍼티 값을 타겟 객체에 설정하는 기능

사용자 관점: 사용자 입력값을 애플리케이션 도메인 모델에 동적으로 변환해 넣어주는 기능

-> 입력 값인 대부분 "문자열"로 가지고 있고, 그 값을 객체의 int, long, Boolean, Date, Event, Book 같은 도메인 타입으로 변환해서 넣어주는 기능

 

예) 책 구매시 "제목" : "데이터 바인딩", "개수" : "3" 처럼 문자열 입력시 객체는 제목은 String, 개수는 int로 할당 해주는 것입니다.


ProPertyEditer

 

  • 스프링 3.0 이전 까지 DataBinder가 변환 작업 사용하던 인터페이스
  • Thread Safe하지 않음 -> 상태 정보를 저장하고 있기 때문에 싱글톤 빈으로 등록해서 사용시 문제가 있음 
    • 1번 회원이 2번 회원 정보를 변경, 2번 회원이 N번 회원을 변경하는 등의 의도치 않은 자원 공유 문제
    • 빈으로 등록하지 않고 @InitBinder를 통해 DataBinder를 등록해서 사용
  • Object와 String 간의 변환만 사용 가능하기에 사용 범위가 제한적임

 


Converter

 

  • A 타입을 B 타입으로 변환할 수 있는 매우 일반적인 변환기
  • Stateless 상태정보가 없기 때문에 Thread Safe함
  • ConverterRegistry에 등록후 사용
  • 기본적으로 Interger to String 같은 것은 Spring에 이미 등록되어 있음

 

Controller에 간단한 GET 생성

@RestController
public class EventController {

    @GetMapping("/event/{event}")
    public String getEvent(@PathVariable Event event){
        System.out.println(event);
        return event.getId().toString();
    }
}

 

String을 Event 객체로 변환해주는 Converter 생성

String source를 Interger로 파싱하여 새로운 Event객체 생성해주도록 동작

import org.springframework.core.convert.converter.Converter;

public class EventConverter {


    public static class String2EventConverter implements Converter<String, Event> {
        @Override
        public Event convert(String source) {
            return new Event(Integer.parseInt(source));
        }
    }
}

 

WebMvcConfigurer을 상속받아 addFormatter를 통해 ConverterRegistry에 등록해서 사용

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new EventConverter.String2EventConverter());
    }
}

 

Test는 id가 1인 event GET요청시 상태고드 OK와 내용이 문자열 "1" 로 들어가있는지 확인하는 테스트

@ExtendWith(SpringExtension.class)
@WebMvcTest
class EventControllerTest {

    @Autowired
    MockMvc mockMvc;

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


}

Formatter

 

  • PropertyEditor 대체제
  • Object와 String 간의 변환 담당
  • Thread Safe함 -> 빈 등록 가능
  • 문자열을 Locale에 따라 다국화 하는 기능 제공
  • FormatterRegistry에 등록해서 사용

 

다음과 같이 addFormatter를 통해 등록

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new EventFormatter());
    }

}

 

EventFormatter는 다음과 같이 파싱하여 Event 객체를 만들어주고, 원하는 형식의 format으로 print

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

 


ConversionService

 

  • Converter와 Formatter에서는 이전의 PropertyEditor가 아닌 ConversionService를 통해 변환 작업진행
    • 이 인터페이스를 통해 Thread Safe하도록 사용가능하게 해줌
  • 스프링MVC, 빈, SpEL에서 사용
  • DefaultFormattingConversionService
    • FormatterRegistry
    • ConversionService
    • 여러 기본 Converter, Formatter 등록
    • 스프링 부트는 해당 클래스를 상속받아서 WebConversionService를 빈으로 등록 및 Formatter와 Converter를 빈으로 자동 등록 시켜줌

 

JPA를 이용시에는 JPA에 이미 Entity 필드의 Converter가 등록되어 있습니다.

'Spring Boot > Core' 카테고리의 다른 글

스프링 AOP  (0) 2022.08.01
SpEL  (0) 2022.07.30
Validation 추상화  (0) 2022.07.25
Resource 추상화  (0) 2022.07.25
IoC 컨테이너와 빈  (0) 2022.07.19

댓글