상세 컨텐츠

본문 제목

[Spring] Return Value Handler 개념 / Custom Return Value Handler 생성

Spring/개념

by Chan.94 2024. 6. 17. 22:49

본문

반응형

Return Value Handler란


HandlerMethodReturnValueHandler를 줄여서 Return Value Handler라고 한다.

Argument Resolver가 요청 데이터를 처리하듯 Return Value Resolver는 그와 반대로 응답 데이터를 처리한다.

 

Argument Resolver에 대한 내용을 알아야 쉽게 받아 들 일 수 있다.

[Spring/개념] - [Spring] Argument Resolver 개념 / Custom Argument Resolver 생성

 

 

ReturnValueHandler는 Handler(Controller)의 반환값을 가지고 별도의 로직을 수행한 후 Handler Adapter에게 반환한다.

 

 

Custom Value Handler 생성


ReturnValueHandler를 만들기 위해서는 HandlerMethodReturnValueHandler를 상속받은 객체를 만들어야 한다.

supportsReturnType과 handleReturnValue 두 개의 메서드를 구현해야 한다.

public interface HandlerMethodReturnValueHandler {

   boolean supportsReturnType(MethodParameter returnType);

   void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
         ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;

}
  • supportsReturnType : 어떤 리턴 타입을 처리할 것인지 확인한다.
  • handReturnValue : 리턴 값으로 어떤 작업을 할 것인지 구현한다.

Argument Resolver와 이름만 다르지 수행하는 내용은 거의 동일하다.


Step1. CustomReturnValueHandler 생성 (HandlerMethodReturnValueHandler 상속받은 객체 구현)

Step2. ReturnValueHandler 등록

@Configuration
public class WebConfig implements WebMvcConfigurer{

    @Autowired
    private CustomReturnValueHandler customReturnValueHandler;

    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        handlers.add(customReturnValueHandler);
    }
}

WebMvcConfigurer를 구현한 Configuration 클래스에 생성한 Return Value Hanlder를 등록한다.


RequestMappingHandlerAdapter.java

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean {

    @Override
    protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        ModelAndView mav;
        ...
        mav = invokeHandlerMethod(request, response, handlerMethod);
        ...
        return mav;
    }


    protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        ...
        ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
        ModelAndViewContainer mavContainer = new ModelAndViewContainer();
        ...

        // Handler 호출
        invocableMethod.invokeAndHandle(webRequest, mavContainer);

        return getModelAndView(mavContainer, modelFactory, webRequest);
    }
}

RequestMappingHandlerAdapter에서 Handler(Controller)가 실행되는 주요 소스이다.

ModelAndViewContainer에 Handler(Controller) 실행 결과가 담기게 된다.

 

ServletInvocableHandlerMethod.java

public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
    public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

        try {
            this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
        }
        catch (Exception ex) {
            if (logger.isTraceEnabled()) {
                logger.trace(formatErrorForReturnValue(returnValue), ex);
            }
            throw ex;
        }
    }
}

 

Handler(Controller) 실행 이후 반환값으로 Object 타입의 returnValue가 반환되고 Return Value Handler가 실행되는 것을 확인할 수 있다.

 

앞서 정의한 supportsReturnType를 통해 어떤 ReturnValueHandler를 사용할 것인지 결정되었고 handleReturnValue메서드가 실행된다.


DispatcherServlet에서 HandlerReturnValue가 어떤 시점에 호출되는지 소스레벨로 보고싶다면 아래 포스팅을 확인하기 바란다.

Dispatcher Servlet 파헤치기 (Argument Resolver, ReturnValue Handler, Controller 실행시점)

반응형

관련글 더보기

댓글 영역

>