在学习 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
的方法如果处理程序支持该类型( String
、 View
、 ResponseEntity
、 etc. (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/