개요
이전에는 컨트롤러에 들어오는 파라미터를 가공하는 방법에 대해 알아보았는데, 이번에는 반대로 리턴타입을 기준으로 분기할 수 있는 ReturnValueHandler를 구현해보려 한다. 기존에는 ModelAndViewResolver를 구현해서 AnnotationMethodHandlerAdapter에 등록을 해야 했는데, 스프링 3.2버전 부터는 deprecated 된 상태다. 지금은 ModelAndViewResolver는 남아 있기는 하나 앞으로 HandlerMethodReturnValueHandler 사용하기를 권하고 있다. 모든 HandlerMethodReturnValueHandler를 검색해봐도 리턴된 클래스를 처리 하는 핸들러를 못 찾을 경우에만 ModelAndViewResolver를 검색하기 시작한다.
예제
이전에 파라미터를 Map 형태로 수집하는 클래스를 만들었는데, 이번에는 그 안에 내용에 따라 view를 분기 시켜보려 한다. 파라미터 수집하는 예제는 (http://jekalmin.tistory.com/entry/%EC%BB%A4%EC%8A%A4%ED%85%80-ArgumentResolver-%EB%93%B1%EB%A1%9D%ED%95%98%EA%B8%B0) 이 글을 참고하길 바란다. 먼저 HandlerMethodReturnValueHandler를 구현한 클래스를 생성하고 dispatcherServlet에 등록해주자.
ParamCollectorReturnValueHandler.java
package com.tistory.jekalmin;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
public class ParamCollectorReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
// TODO Auto-generated method stub
return ParamCollector.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public void handleReturnValue(Object returnValue,
MethodParameter returnType, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
// TODO Auto-generated method stub
ParamCollector collector = (ParamCollector)returnValue;
if(collector.get("viewType").equals("json")){
// json View 등록
System.out.println("json View 등록하는 곳");
}
}
}
다음 dispatcherServlet의 설정이다.
mvc-config.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"
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:return-value-handlers>
<bean class="com.tistory.jekalmin.ParamCollectorReturnValueHandler"></bean>
</mvc:return-value-handlers>
</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 이다.
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 {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping("/index")
public ParamCollector index(ParamCollector collector){
System.out.println(collector);
return collector;
}
}
http://localhost:8080/test/index?viewType=json 일때만 아래 글이 출력되는 것을 확인할 수 있다.
json View 등록하는 곳
결론
HandlerMethodReturnValueHandler를 구현하면 리턴타입이나 리턴된 데이터에 따라서 내가 원하는 view로 보낼 수 있다. 그 View는 흔히 사용하는 JstlView가 될 수도 있지만, AbstractView 등을 구현하여 커스터마이징 해서 사용할 수도 있다.