어제 스터디에서 mvc 프레임워크를 구현하는 중에 나온 이슈 사항입니다. 요구사항은 HttpServletRequest에 담겨 전달되는 인자를 JavaBean에 자동으로 값을 set할 수 있으면 좋겠다. 대부분의 mvc 프레임워크가 이 같은 기능을 제공하고 있기 때문에 우리도 만들어보자는 의도에서 시작했다.
구현은 java reflection 사용해서 쉽게 해결할 수 있었다. 그런데 문제는 String Type이 아닌 다른 데이터 타입일 경우에 어떻게 처리하는 것이 좋을까에 대해서는 해결책을 찾지 못했다. if/else를 사용한다면 다음과 같은 방식으로 구현하는 것이 가능하다.
package net.slipp.web;
import java.lang.reflect.Field;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockHttpServletRequest;
public class ReflectionTest {
private static Logger log = LoggerFactory.getLogger(ReflectionTest.class);
@Test
public void populateFromRequestToUser() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("userId", "test");
request.addParameter("name", "슬립");
request.addParameter("userNo", "12356");
request.addParameter("age", "35");
MockUser user = new MockUser();
Field[] fields = MockUser.class.getDeclaredFields();
for (Field field : fields) {
log.debug("field name : {}", field.getName());
field.setAccessible(true);
String value = request.getParameter(field.getName());
if (field.getType() == Integer.class) {
field.set(user, Integer.parseInt(value));
} else if (field.getType() == Long.TYPE) {
field.set(user, Long.parseLong(value));
} else {
field.set(user, value);
}
}
log.debug("User : {}", user);
}
private class MockUser {
private long userNo;
private Integer age;
private String userId;
private String name;
@Override
public String toString() {
return "MockUser [userNo=" + userNo + ", age=" + age + ", userId=" + userId + ", name=" + name + "]";
}
}
}
그런데 위와 같이 구현할 경우 모든 데이터 타입에 대한 if/else를 추가해야 되고, Custom Type이 존재할 경우에는 해결 방법이 없는 상황이다. 일단 Custom Type은 제외하더라도 자바에서 제공하는 기본 데이터 타입에 대해 쉽게 형 변환을 할 수 있는 방법이 있을까?
3개의 의견 from SLiPP
Spring MVC에서 자동을 conversion을 해주고 있어서 소스를 열어 봤더니 이런 부분이 보이네요. PropertyEditorRegistrySupport.java 파일입니다.
위와 같이 Map으로 Type에 각 Type에 따른 형변환을 할 수 있는 PropertyEditor 클래스를 두어서 관리하도록 구현하고 있네요. 이런 방식으로 구현하면 if/else는 사라지고 CustomType이 추가될 경우 이 Map에다 CustomType과 이에 대한 CustomPropertyEditor를 추가하는 방식으로 구현하면 되겠네요. 위 본문에 있는 소스 코드를 위와 같이 한번 구현해 봐야겠네요.
Spring 소스에서 일부 Type을 가져온 다음 아래와 같이 수정해서 구현해 봤습니다. 모든 Type을 고려하려면 Spring MVC 소스 보세요.
이미 적으셨지만 이런 목적으로 만든 자바의 기능이 PropertyEditor이죠.
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.