본문 바로가기

카테고리 없음

[Spring] 스프링 데이터 바인딩 추상화: PropertyEditor

반응형

| 스프링 데이터 바인딩

데이터바인딩이란 프로퍼티의 값을 타겟 객체에 설정하는 기능이다.

스프링에서 데이터 바인딩은 org.spring.framework.validation.DataBinder 인터페이스를 사용하여 사용자 입력값을 애플리케이션의 도메인 모델에 동적으로 변환하여 넣어주는 기술을 의미한다.

사용자가 입력하는 값은 주로 문자열이지만 객체가 가진 다양한 프로퍼티의 타입 (int, long, Date 등)으로 변환할 수 있다.

 

| PropertyEditor 인터페이스

  • 스프링 3.0 이전까지는 DataBinder가 변환 작업을 위해 ProertyEditor 인터페이스를 사용
  • 쓰레드-세이프 하지 않음 (상태정보를 저정하고 있음, 싱글톤 빈으로 사용X)
  • Object <-> String 간의 변환만 제공하기 때문에 사용이 제한적

PropertyEditor 인터페에스의 메소드를 모두 구현할 필요 없이 PropertyEditor의 구현 객체인 PropertyEdiotSupoort를 상속받아 아래와 같이 String <-> Event로 변환하는 코드는 다음과 같다. 

package com.example.demo;

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 + '\'' +
                '}';
    }
}
import java.beans.PropertyEditorSupport;

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

 

import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EventController {

    @InitBinder
    public void init(WebDataBinder webDataBinder) {
        webDataBinder.registerCustomEditor(Event.class, new EventEditor());
    }

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

 

테스트 코드

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.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"));
    }
}

 

PropertyEditor의 단점들을 극복하기 위해 스프링 3.0부터 Convertor와 Formatter가 도입되었다.

반응형