java - Controller 处理程序方法支持的返回类型

标签 java spring spring-mvc

在学习 Spring 框架时,我注意到 Spring in Action 一书中,作者没有在 Controller 中使用 ModelandView 方法返回类型。作者将 Controller 方法声明为 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 注释的 Controller 方法的包装器.

这通常会经过一堆方法调用,最终在 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 的接口(interface)返回 true 的方法如果处理程序支持该类型( StringViewResponseEntityetc. (look for supported return types) )。因此该方法返回它找到的第一个支持该类型的处理程序并运行它。

Spring 在初始化时注册了一系列 HandlerMethodReturnValueHandler 的实现。 .基本上都是known implementing classes in its javadoc .

例如,如果您返回一个字符串,Spring 将使用一个 ViewNameMethodReturnValueHandler 。处理响应。

现在,使用哪种返回类型由您决定。如果你想返回 Model所以你可以在你的jsp View 中使用请求属性,你可以让Spring传递一个Model实例到您的方法,或者您可以创建 Model反对自己并将其传递给 ModelAndView你的返回。在大多数情况下,这是一个风格问题。

关于java - Controller 处理程序方法支持的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18242454/

相关文章:

java - 使用 jar 中的拦截器绑定(bind)

java - 如何使用 robovm (libgdx) 添加共享意图?

spring - LocalContainerEntityManagerFactoryBean 和 LocalEntityManagerFactoryBean 有什么区别?

html - 发送后重置表单 - Spring-MVC

spring - 如何在 View 中显示所有 Controller 和映射

spring-mvc - 如何限制或拒绝对特定文件夹或文件的访问?

java - 当我尝试使用网络 IP ping 我自己的电脑时,出现 java.net.UnknownHostException 的原因可能是什么?

java - 当 Java 方法需要 Reader/Writer 参数时,是否可以避免使用临时文件?

java - jboss spring applicationContext 在 web.xml 中启动时加载

java - 在jsp中打印 session 属性