Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 控制器处理程序方法支持的返回类型_Java_Spring_Spring Mvc - Fatal编程技术网

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

Java 控制器处理程序方法支持的返回类型,java,spring,spring-mvc,Java,Spring,Spring Mvc,在学习Spring框架时,我注意到在《Spring in Action》一书中,作者没有在控制器中使用ModelandViewmethod返回类型。作者将控制器方法声明为返回类型为String,方法中的return子句只是返回一个字符串,例如return”/views/theview” 有人能详细说明一下这种方法的内在区别吗?这里有一个深入的介绍 Spring提供了一个DispatcherServlet类,通常用于处理您的所有请求。它在其doDispatch(HttpServletRequest

在学习Spring框架时,我注意到在《Spring in Action》一书中,作者没有在控制器中使用
ModelandView
method返回类型。作者将控制器方法声明为返回类型为
String
,方法中的return子句只是返回一个字符串,例如
return”/views/theview”


有人能详细说明一下这种方法的内在区别吗?

这里有一个深入的介绍

Spring提供了一个
DispatcherServlet
类,通常用于处理您的所有请求。它在其
doDispatch(HttpServletRequest请求,HttpServletResponse响应)
方法中实现了这一点

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
其中,
mv
是最终的
ModelAndView
对象,
ha
是控制器方法的包装,用
@RequestMapping
注释

这通常会经过一堆方法调用,最后到达
servleinvaccableHandlerMethod.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)返回适当的处理程序。是一个带有
supportsReturnType
方法的接口,如果处理程序支持该类型(
String
View
ResponseEntity
,),该方法将返回
true
)。因此,该方法返回它找到的第一个支持该类型的处理程序并运行它

Spring在初始化时注册了一整套
HandlerMethodReturnValueHandler
的实现。基本上是所有的

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


现在,使用哪种返回类型取决于您。如果您想返回一个
模型
,以便在jsp视图中使用请求属性,您可以让Spring将
模型
实例传递给您的方法,或者您可以自己创建
模型
对象,并将其传递给返回的
模型和视图
。在大多数情况下,这是一个风格问题。

这里有一个深入的介绍

Spring提供了一个
DispatcherServlet
类,通常用于处理您的所有请求。它在其
doDispatch(HttpServletRequest请求,HttpServletResponse响应)
方法中实现了这一点

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
其中,
mv
是最终的
ModelAndView
对象,
ha
是控制器方法的包装,用
@RequestMapping
注释

这通常会经过一堆方法调用,最后到达
servleinvaccableHandlerMethod.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)返回适当的处理程序。是一个带有
supportsReturnType
方法的接口,如果处理程序支持该类型(
String
View
ResponseEntity
,),该方法将返回
true
)。因此,该方法返回它找到的第一个支持该类型的处理程序并运行它

Spring在初始化时注册了一整套
HandlerMethodReturnValueHandler
的实现。基本上是所有的

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


现在,使用哪种返回类型取决于您。如果您想返回一个
模型
,以便在jsp视图中使用请求属性,您可以让Spring将
模型
实例传递给您的方法,或者您可以自己创建
模型
对象,并将其传递给返回的
模型和视图
。在大多数情况下,这是一个风格问题。

功能方面没有区别,两者是等效的:

@RequestMapping(..)
public String requestMapping1(Model model){
    model.addAttribute("attr1", attr1);
    return "viewName";
}

@RequestMapping(..)
public ModelAndView requestMapping2(){
    ModelAndView modelAndView = new ModelAndView("viewName");
    modelAndView.addObject("attr1", attr1);
    return modelAndView;
}

然而,首选的方法是前者,这也是作者没有在书样本中使用后者的原因。

功能方面没有区别,两者是等效的:

@RequestMapping(..)
public String requestMapping1(Model model){
    model.addAttribute("attr1", attr1);
    return "viewName";
}

@RequestMapping(..)
public ModelAndView requestMapping2(){
    ModelAndView modelAndView = new ModelAndView("viewName");
    modelAndView.addObject("attr1", attr1);
    return modelAndView;
}

然而,首选的方法是前者,这就是作者没有在书样本中使用后者的原因。

在spring源代码中,您可以看到此类
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
。在方法
publicmodelandview getModelAndView(…)
中,您可以获得spingmvc如何生成
ModelAandView
对象

if (returnValue instanceof HttpEntity) { // returnValue is returned Value of Handler method
            handleHttpEntityResponse((HttpEntity<?>) returnValue, webRequest);
            return null;
        }
        else if (AnnotationUtils.findAnnotation(handlerMethod, ResponseBody.class) != null) {
            handleResponseBody(returnValue, webRequest);
            return null;
        }
        else if (returnValue instanceof ModelAndView) {
            ModelAndView mav = (ModelAndView) returnValue;
            mav.getModelMap().mergeAttributes(implicitModel);
            return mav;
        }
        else if (returnValue instanceof Model) {
            return new ModelAndView().addAllObjects(implicitModel).addAllObjects(((Model) returnValue).asMap());
        }
        else if (returnValue instanceof View) {
            return new ModelAndView((View) returnValue).addAllObjects(implicitModel);
        }
        else if (AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class) != null) {
            addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel);
            return new ModelAndView().addAllObjects(implicitModel);
        }
        else if (returnValue instanceof Map) {
            return new ModelAndView().addAllObjects(implicitModel).addAllObjects((Map) returnValue);
        }
        else if (returnValue instanceof String) { // String is here, return new ModelAndView
            return new ModelAndView((String) returnValue).addAllObjects(implicitModel);
        }
if(HttpEntity的returnValue instanceof){//returnValue是Handler方法的返回值
handleHttpEntityResponse((HttpEntity)返回值,webRequest);
返回null;
}
else if(AnnotationUtils.findAnnotation(handlerMethod,ResponseBody.class)!=null){
HandlerResponseBody(返回值,webRequest);
返回null;
}
else if(返回ModelAndView的值实例){
ModelAndView mav=(ModelAndView)返回值;
mav.getModelMap().mergeAttributes(隐式模型);
返回mav;
}
else if(模型的返回值实例){
返回新的ModelAndView().addAllObject(隐式模型).addAllObject(((模型)returnValue.asMap());
}
else if(返回视图的值实例){
返回新模型和视图((视图)返回值);
}
else if(AnnotationUtils.FindAnotation(handlerMethod,ModelAttribute.class)!=null){
addReturnValueAsModelAttribute(handlerMethod、handlerType、returnValue、implicitModel);
返回新的ModelAndView().AddAllObject(隐式模型);
}
else if(返回值