Spring/스프링 프레임워크 핵심 원리

[Spring] #15. 데이터 바인딩 추상화: PropertyEditor

sujin7837 2020. 12. 24. 20:27
반응형

데이터 바인딩

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

-사용자 관점: 사용자의 입력값을 애플리케이션 도메인 모델에 동적으로 할당하는 기능, 즉 입력값은 '문자열'인데, 그 값을 int, long, boolean, date 등 또는 Event, Book 같은 도메인 타입 그 자체로 변환해야 하는 경우 변환해주는 기능

-DataBinder 인터페이스: 여러 곳에서 쓰이는 스프링의 핵심 기술 중 하나로 데이터 바인딩에 관한 기능을 여러 인터페이스로 적절히 추상화시켜놓음

 

//Event.java

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;
    }
}
//EventController.java

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

@Runwith(SpringRunner.class)
@WebMvcTest
public class EventControllerTest {
    @Autowired
    MockMvc mockMvc;
    
    @Test
    public void getTest() throws Exception {
        mocMvc.perform(get(urlTemplate: "/event/1"))
                            .andExpect(status().isOk())
                            .andExpect(content().string(expectedContent: "1"));

    //"/event/1"을 요청으로 보내면 응답으로 '200'이 나와서 문제가 없어야 하고, 결과가 '1'이 나와야 함
    //그러나 "/event/1"의 '1' 부분을 이벤트로 읽어오지 못하므로 에러가 발생함(문자열 '1'을 숫자 1로 읽지 못함)
    }
}

 

 

PropertyEditor

위의 에러 발생 문제를 해결(문자열을 숫자로 바꿔줌)하기 위해 PropertyEditor를 작성합니다

//EventEditor.java

public class EventEditor extends PropertyEditorSupport {

    @Override
    public String getAsText() {
        Event event=(Event)getValue();
        return event.getId().toString();
    }

    @Override
    public void setAsText(String text) throws IlligelArgumentException {
        setValue(new Event(Integer.parseInt(text)));
    }
}

***PropertyEditor는 가급적 빈으로 등록해서 사용하면 안됩니다!!(다른 스레드와 공유해서 쓰지 않는 것이 안전합니다)***

 

//EventController.java

@RestController
public class EventController {
    @InitBinder
    public void init(WebDataBinder webDataBinder) {
        webDataBinder.registerCustomEditor(Event.class, new EventEditor());
    }
    //PropertyEditor를 빈으로 등록할 수 없으므로 컨트롤러에 등록해서 사용합니다
    //컨트롤러에서 정의한 WebDataBinder에 들어있는 PropertyEditor를 사용하게 됩니다.

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

-프로퍼티 에디터의 단점

·구현이 편리하지 않음

·스레드 세이프하지 않기 때문에 빈으로 등록해서 사용하기 위험함

반응형