홍이의 개발 노트

Spring 3.1 @MVC에서 컨트롤에서 리턴되는 타입( 또는 어노테이션 )에 따른 처리 본문

개발이야기/스프링(Spring)

Spring 3.1 @MVC에서 컨트롤에서 리턴되는 타입( 또는 어노테이션 )에 따른 처리

코바 2011. 6. 28. 10:05


저번에 포스팅 했던 AnnotationMethodHandlerAdapter.class 에서 있는 내용이다

  @SuppressWarnings("unchecked")
  public ModelAndView getModelAndView(Method handlerMethod, Class handlerType, Object returnValue,
    ExtendedModelMap implicitModel, ServletWebRequest webRequest) throws Exception {
// 메소드가 @ResponseStatus 어노 테이션을 찾는다
   ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(handlerMethod, ResponseStatus.class);
   if (responseStatusAnn != null) {
    HttpStatus responseStatus = responseStatusAnn.value();
    String reason = responseStatusAnn.reason();
    if (!StringUtils.hasText(reason)) {
     webRequest.getResponse().setStatus(responseStatus.value());
    }
    else {
     webRequest.getResponse().sendError(responseStatus.value(), reason);
    }

    // to be picked up by the RedirectView
    webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, responseStatus);

    responseArgumentUsed = true;
   }

   // Invoke custom resolvers if present...
// 사용자 정의 ModelAndViewResolvers를 가지고 있는지 확인 후 있으면 있는 수만큼 실행한다.
   if (customModelAndViewResolvers != null) {
    for (ModelAndViewResolver mavResolver : customModelAndViewResolvers) {
     ModelAndView mav = mavResolver.resolveModelAndView(
       handlerMethod, handlerType, returnValue, implicitModel, webRequest);
     if (mav != ModelAndViewResolver.UNRESOLVED) {
      return mav;
     }
    }
   }
// 리턴되는 객체가 HttpEntity 클래스이면 
if (returnValue instanceof HttpEntity) {
    handleHttpEntityResponse((HttpEntity<?>) returnValue, webRequest);
    return null;
   }
// 메소드에 @ResponseBody 어노테이션이 붙여 있는지
   else if (AnnotationUtils.findAnnotation(handlerMethod, ResponseBody.class) != null) {
    handleResponseBody(returnValue, webRequest);
    return null;
   }
// 리턴되는 객체가 ModelAndView 클래스이면
   else if (returnValue instanceof ModelAndView) {
    ModelAndView mav = (ModelAndView) returnValue;
    mav.getModelMap().mergeAttributes(implicitModel);
    return mav;
   }
// 리턴되는 객체가 Model 클래스이면
   else if (returnValue instanceof Model) {
    return new ModelAndView().addAllObjects(implicitModel).addAllObjects(((Model) returnValue).asMap());
   }
// 리턴되는 객체가 View 클래스이면
   else if (returnValue instanceof View) {
    return new ModelAndView((View) returnValue).addAllObjects(implicitModel);
   }
//  메소드에 @ModelAttribute 어노테이션이 붙여 있는지 
   else if (AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class) != null) {
    addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel);
    return new ModelAndView().addAllObjects(implicitModel);
   }
// 리턴되는 객체가 Map 클래스이면
   else if (returnValue instanceof Map) {
    return new ModelAndView().addAllObjects(implicitModel).addAllObjects((Map) returnValue);
   }
// 리턴되는 객체가 String 클래스이면 ( 문자열이면 )
   else if (returnValue instanceof String) {
    return new ModelAndView((String) returnValue).addAllObjects(implicitModel);
   }
// 리턴되는 객체가 null 이면 ( 즉 void 이면 )
   else if (returnValue == null) {
    // Either returned null or was 'void' return.
    if (this.responseArgumentUsed || webRequest.isNotModified()) {
     return null;
    }
    else {
     // Assuming view name translation...
     return new ModelAndView().addAllObjects(implicitModel);
    }
   }
/* 이것이 뭔가 해서 소스 따라 가보니  
 * a primitive, a String or other CharSequence, a Number, a Date,
  * a URI, a URL, a Locale, a Class, or a corresponding array.
  즉 int, float 등 기본형 타입 또는 레퍼타입 String, URL, URI 등 기본 형태의 자료형이다.
  리턴 되는 객체가 이 타입을 반환 했을 때 실행되는 부분이다. */
   else if (!BeanUtils.isSimpleProperty(returnValue.getClass())) {
    // Assume a single model attribute...
    addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel);
    return new ModelAndView().addAllObjects(implicitModel);
   }
   else {
// 위에서 핸들링 하지 못한 리턴 타입이 있으면 에러 발생
    throw new IllegalArgumentException("Invalid handler method return value: " + returnValue);
   }
  }


대략 리턴 되는 타입 또는 어노테이션에 대응해서 실행된는 코드를 살펴 봤다
역시 스프링은 공부할게 천지 인듯하다.