'ArgumentResolver'에 해당되는 글 1건

  1. 커스텀 ArgumentResolver 등록하기 (2)

커스텀 ArgumentResolver 등록하기

개요

스프링 사용시 컨트롤러에 들어오는 파라미터나 리턴타입을 나한테 맞게 가공해서 사용하고 싶을 때가 있다.. 기존에는 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를 활용하면 파라미터 수집 이 외에도 다양하게 커스터마이징 할 수 있다. 어떻게 활용하느냐는 여러분에게 달려있다.