当前位置: 首页 > 面试题库 >

控制器处理程序方法支持的返回类型

宦翔
2023-03-14
问题内容

在学习Spring框架时,我在《 Spring in Action
》一书中注意到,作者并未ModelandView在控制器中使用方法返回类型。作者将控制器方法声明为的返回类型,String并且该方法中的return子句仅返回诸如以下的字符串return "/views/theview";

有人可以详细说明其工作方式的内部差异吗?


问题答案:

这是深入了解。

Spring提供了一个DispatcherServlet通常处理所有请求的类。它以其doDispatch(HttpServletRequest request, HttpServletResponse response)方法做到这一点

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

mv最终ModelAndView对象在哪里,ha是用注释的控制器方法的包装@RequestMapping

这通常会经过一堆方法调用,最终以 ServletInvocableHandlerMethod.invokeAndHandle

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle
at org.springframework.web.servlet.DispatcherServlet.doDispatch

看源头

public final void invokeAndHandle(ServletWebRequest webRequest,
                ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

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

    setResponseStatus(webRequest);

    if (returnValue == null) {
        if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
            mavContainer.setRequestHandled(true);
            return;
        }
    } else if (StringUtils.hasText(this.responseReason)) {
        mavContainer.setRequestHandled(true);
        return;
    }

    mavContainer.setRequestHandled(false);

    try {
        this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
    }
    catch (Exception ex) {
        if (logger.isTraceEnabled()) {
            logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
        }
        throw ex;
    }
}

returnValue是您的@RequestMapping方法返回的对象。它经历了

this.returnValueHandlers.handleReturnValue

Spring确定HandlerMethodReturnValueHandler要处理该对象的位置。

public void handleReturnValue(
        Object returnValue, MethodParameter returnType,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
        throws Exception {

    HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType); // returns the appropriate handler
    Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]");
    handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}

getReturnValueHandler(returnType);返回适当的处理程序。的HandlerMethodReturnValueHandler是具有一个接口supportsReturnType方法,该方法返回true,如果处理程序支持该类型(StringViewResponseEntity,等。(外表支持的返回类型))。因此,该方法返回它找到的第一个处理程序,该处理程序支持该类型并运行它。

Spring在初始化时会注册的完整实现HandlerMethodReturnValueHandler。基本上所有已知的实现类都在其javadoc中。

例如,如果您返回一个String,Spring将使用a
ViewNameMethodReturnValueHandler来处理响应。

现在,由您决定使用哪种返回类型。如果要返回a
Model以便可以在jsp视图中使用请求属性,则可以让Spring将Model实例传递给方法,也可以Model自己创建对象并将其传递给ModelAndView返回的对象。在大多数情况下,这都是风格问题。



 类似资料:
  • @ExceptionHandler在控制器内调用时返回带有MyResponse对象的200响应,但从ControllerAdvice调用时返回带有一般404消息的404。我希望它返回一个带有MyResponse对象的200响应。 下面是Controller和ControllerAdvice中的异常处理代码。在测试ControllerAdvision时,我在控制器中注释了它。调试显示在Control

  • 我正在使用JBoss6.1、Spring3.2、hibernate验证以及最近启用的CORS支持。请求与GET方法配合良好。如果使用请求方法POST,我希望控制器返回405。但我得到的是http状态码400。我在jboss日志中启用了跟踪,发现spring返回了错误的处理程序。应用程序只有一个控制器接受POST请求方法,其余控制器定义为只接受GET方法。每当使用POST请求方法对这些控制器(用GE

  • 本文向大家介绍ThinkPHP处理Ajax返回的方法,包括了ThinkPHP处理Ajax返回的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了ThinkPHP处理Ajax返回的方法,分享给大家供大家参考。具体实现方法如下: 在ThinkPHP中可以直接使用ajax返回: 而在处理过程中可以使用这个函数处理: 希望本文所述对大家的ThinkPHP框架程序设计有所帮助。

  • 本文向大家介绍ajax处理服务器返回的三种数据类型方法,包括了ajax处理服务器返回的三种数据类型方法的使用技巧和注意事项,需要的朋友参考一下 其原理很简单,结构上基本不变,只是改变处理返回数据的方式. 1.Text/HTML格式 这种返回类型处理很简单,直接就当作字符串用就行了.为了方便使用,封装成如下函数: 服务器端返回数据格式如下: 例如: 调用格式如下: 2.XML格式 返回的是一个XML

  • 我在一个spring MVC控制器中有一个简单的REST方法,如下所示,它有一个签名: @RequestMapping(value=“/person/{personId}”,method=RequestMethod.Get)public@ResponseBody对象getPerson(@PathVariable(“personId”)String personId){ ...} 输出为类型,因为从

  • 问题内容: 我昨天在JavaFX中构建了一个小应用程序。我想在Controller类中获取应用程序的场景。每次尝试在控制器类中获取场景时,都会出错。我可以在Controller类的Button上设置OnKeyPressed方法,效果很好。但是,只有在选择Button后,它才能正常工作。我只能在Main类方法replaceSceneContent中获得场景。我已经读过这个问题,但是我在initial