개요
스프링 사용시 컨트롤러에 들어오는 파라미터나 리턴타입을 나한테 맞게 가공해서 사용하고 싶을 때가 있다.. 기존에는 WebArgumentResolver를 구현해서 AnnotationMethodHandlerAdapter에 등록을 해야 했는데, 스프링 3.2버전 부터는 deprecated 된 상태다. 지금은 RequestMappingHandlerAdapter 클래스가 담당하는데, 이 클래스에서는 WebArgumentResolver가 HandlerMethodArgumentResolver로 바뀌었다.
예제
request 파라미터 수집을 Map 형태로 하는 클래스를 만들어서 등록해보자. 먼저 Spring Project로 생성한 뒤, 파라미터 수집하는 클래스를 생성하자.
ParamCollector.java
package com.tistory.jekalmin;
import java.util.HashMap;
import java.util.Map;
public class ParamCollector {
Map<String, String> map = new HashMap<String, String>();
public String get(String key){
return map.get(key);
}
public void put(String key, String value){
map.put(key, value);
}
public String toString() {
return map.toString();
}
}
여기서 주의해야 할 점은 Map을 상속 받거나 구현하면, 다른 ArgumentResolver로 갈 수도 있다. 다음은 ArgumentResolver를 구현해서 DispatcherServlet에 등록해주자.
ParamCollectorArgumentResolver.java
package com.tistory.jekalmin;
import java.util.Iterator;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
public class ParamCollectorArgumentResolver implements HandlerMethodArgumentResolver{
@Override
public boolean supportsParameter(MethodParameter parameter) {
// TODO Auto-generated method stub
return ParamCollector.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
// TODO Auto-generated method stub
ParamCollector collector = new ParamCollector();
for(Iterator<String> iterator = webRequest.getParameterNames(); iterator.hasNext();){
String key = iterator.next();
collector.put(key, webRequest.getParameter(key));
}
return collector;
}
}
mvc-config.xml (dispatcherServlet 설정파일)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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">
<context:component-scan base-package="com.tistory.jekalmin"/>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.tistory.jekalmin.ParamCollectorArgumentResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
이제 테스트를 위한 컨트롤러를 생성한다.
TestController.java
package com.tistory.jekalmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/index")
public void index(ParamCollector collector){
System.out.println(collector);
}
}
다음 http://localhost:8080/test/index?aaa=bbb&ccc=ddd로 호출을 해결과는 다음과 같다.
{aaa=bbb, ccc=ddd}
결론
ArgumentResolver를 활용하면 파라미터 수집 이 외에도 다양하게 커스터마이징 할 수 있다. 어떻게 활용하느냐는 여러분에게 달려있다.