Spring에서 custom converter 만들어 사용하기

스프링 @MVC를 사용하면

컨트롤러에 URL과 일치하는 함수를 구현해야 하는데,

URL에 파라미터가 존재할 때, 함수 파라미터를 지정하면 기본 타입(ENUM, INT, STRING, ...)인 경우 자동으로 바인딩 된다.

하지만 ENUM은 ENUM에 정의한 상수 이름과 일치해야 자동으로 바인딩 되는데, 상수 이름이 아닌 값으로도 바인딩 되도록 하고 싶었다.


자동 바인딩 되는 예)

enum{BASIC(0), GOLD(1)}

url?enum=BASIC


자동으로 되지 않는 예)

enum{BASIC(0), GOLD(1)}

url?enum=1


ENUM에 정의된 숫자값으로도 자동 바인딩될 수 있도록 사용자 정의 컨버터를 구현해야 한다.


구현 방법

Converter interface를 상속하여 사용자 정의 컨버터를 구현

사용자 정의 컨버터를 xml에 추가



root-context.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Root Context: defines shared resources visible to all other web components --> <!-- Converter --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer" /> </property> </bean> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService" ref="conversionService" /> </bean> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.yakolla.mytest.MyStringToLevel" /> </list> </property> </bean> </beans>


servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven conversion-service="conversionService" /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <context:component-scan base-package="com.yakolla.mytest" /> </beans:beans>


Level.java

public enum Level { BASIC(0), GOLD(1); private int m_value; private Level(int value) { m_value = value; } public int getValue() { return m_value; } static public Level valueOf(int value) { switch(value) { case 0: return BASIC; case 1: return GOLD; default: throw new AssertionError("Unknown value : " + value); } } }


MyStringToLevel.java

public class MyStringToLevel implements Converter<String, Level> { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); @Override public Level convert(String arg0) { // TODO Auto-generated method stub logger.info("convert {}.", arg0); return Level.valueOf(Integer.valueOf(arg0)); } }


HomeController.java

/** * Handles requests for the application home page. */ @Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); @RequestMapping(value = "/test", method = RequestMethod.GET) public String home(@RequestParam Level level) { logger.info("Welcome home! The client locale is {}.", level); return "home"; } }

테스트

http://localhost:8080/mytest/test?level=1


결과

INFO : com.yakolla.mytest.HomeController - Welcome home! The client locale is GOLD.