ModelAndViewContainer related refinements
This commit is contained in:
@@ -41,7 +41,6 @@ import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@@ -67,13 +66,14 @@ import org.springframework.web.method.annotation.support.RequestHeaderMapMethodA
|
||||
import org.springframework.web.method.annotation.support.RequestHeaderMethodArgumentResolver;
|
||||
import org.springframework.web.method.annotation.support.RequestParamMapMethodArgumentResolver;
|
||||
import org.springframework.web.method.annotation.support.RequestParamMethodArgumentResolver;
|
||||
import org.springframework.web.method.annotation.support.WebArgumentResolverAdapter;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
||||
import org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
@@ -459,13 +459,25 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
|
||||
ServletWebRequest webRequest = new ServletWebRequest(request, response);
|
||||
SessionStatus sessionStatus = new SimpleSessionStatus();
|
||||
|
||||
ModelMap implicitModel = modelFactory.createModel(webRequest, requestMethod);
|
||||
ModelAndView mav = requestMethod.invokeAndHandle(webRequest, implicitModel, sessionStatus);
|
||||
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
|
||||
|
||||
modelFactory.initModel(webRequest, mavContainer, requestMethod);
|
||||
|
||||
requestMethod.invokeAndHandle(webRequest, mavContainer, sessionStatus);
|
||||
|
||||
ModelMap actualModel = (mav != null) ? mav.getModelMap() : null;
|
||||
modelFactory.updateAttributes(webRequest, sessionStatus, actualModel, implicitModel);
|
||||
|
||||
return mav;
|
||||
modelFactory.updateModel(webRequest, mavContainer, sessionStatus);
|
||||
|
||||
if (!mavContainer.isResolveView()) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
ModelAndView mav = new ModelAndView().addAllObjects(mavContainer.getModel());
|
||||
mav.setViewName(mavContainer.getViewName());
|
||||
if (mavContainer.getView() != null) {
|
||||
mav.setView((View) mavContainer.getView());
|
||||
}
|
||||
return mav;
|
||||
}
|
||||
}
|
||||
|
||||
private WebDataBinderFactory createDataBinderFactory(HandlerMethod handlerMethod) {
|
||||
|
||||
@@ -32,8 +32,6 @@ import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.support.WebArgumentResolver;
|
||||
@@ -47,9 +45,10 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ModelAndViewMethodReturnValueHandler;
|
||||
@@ -60,17 +59,15 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebA
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* An extension of {@link AbstractHandlerMethodExceptionResolver} that matches thrown exceptions to
|
||||
* {@link ExceptionHandler @ExceptionHandler} methods in the handler. If a match is found the
|
||||
* exception-handling method is invoked to process the request.
|
||||
* A {@link AbstractHandlerMethodExceptionResolver} that matches thrown exceptions to {@link ExceptionHandler}-annotated
|
||||
* methods. If a match is found the exception-handling method is invoked to process the request.
|
||||
*
|
||||
* <p>See {@link ExceptionHandler} for information on supported method arguments and return values
|
||||
* for exception-handling methods. You can customize method argument resolution and return value
|
||||
* processing through the various bean properties in this class.
|
||||
* <p>See {@link ExceptionHandler} for information on supported method arguments and return values for exception-handling
|
||||
* methods. You can customize method argument resolution and return value processing through the various bean properties
|
||||
* in this class.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
* @see #setMessageConverters(HttpMessageConverter[])
|
||||
*/
|
||||
public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandlerMethodExceptionResolver implements
|
||||
InitializingBean {
|
||||
@@ -79,8 +76,6 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
|
||||
private HttpMessageConverter<?>[] messageConverters;
|
||||
|
||||
private ModelAndViewResolver[] customModelAndViewResolvers;
|
||||
|
||||
private final Map<Class<?>, ExceptionMethodMapping> exceptionMethodMappingCache =
|
||||
new ConcurrentHashMap<Class<?>, ExceptionMethodMapping>();
|
||||
|
||||
@@ -102,9 +97,11 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom ArgumentResolvers to use for special method parameter types.
|
||||
* Set a custom ArgumentResolver to use for special method parameter types.
|
||||
* <p>Such a custom ArgumentResolver will kick in first, having a chance to resolve
|
||||
* an argument value before the standard argument handling kicks in.
|
||||
* <p>Note: this is provided for backward compatibility. The preferred way to do this is to
|
||||
* implement a {@link HandlerMethodArgumentResolver}.
|
||||
*/
|
||||
public void setCustomArgumentResolver(WebArgumentResolver argumentResolver) {
|
||||
this.customArgumentResolvers = new WebArgumentResolver[]{argumentResolver};
|
||||
@@ -114,6 +111,8 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
* Set one or more custom ArgumentResolvers to use for special method parameter types.
|
||||
* <p>Any such custom ArgumentResolver will kick in first, having a chance to resolve
|
||||
* an argument value before the standard argument handling kicks in.
|
||||
* <p>Note: this is provided for backward compatibility. The preferred way to do this is to
|
||||
* implement a {@link HandlerMethodArgumentResolver}.
|
||||
*/
|
||||
public void setCustomArgumentResolvers(WebArgumentResolver[] argumentResolvers) {
|
||||
this.customArgumentResolvers = argumentResolvers;
|
||||
@@ -127,24 +126,6 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom ModelAndViewResolvers to use for special method return types.
|
||||
* <p>Such a custom ModelAndViewResolver will kick in first, having a chance to resolve
|
||||
* a return value before the standard ModelAndView handling kicks in.
|
||||
*/
|
||||
public void setCustomModelAndViewResolver(ModelAndViewResolver customModelAndViewResolver) {
|
||||
this.customModelAndViewResolvers = new ModelAndViewResolver[] {customModelAndViewResolver};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set one or more custom ModelAndViewResolvers to use for special method return types.
|
||||
* <p>Any such custom ModelAndViewResolver will kick in first, having a chance to resolve
|
||||
* a return value before the standard ModelAndView handling kicks in.
|
||||
*/
|
||||
public void setCustomModelAndViewResolvers(ModelAndViewResolver[] customModelAndViewResolvers) {
|
||||
this.customModelAndViewResolvers = customModelAndViewResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link HandlerMethodArgumentResolver}s to use to resolve argument values for
|
||||
* {@link ExceptionHandler} methods. This is an optional property.
|
||||
@@ -207,9 +188,14 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
returnValueHandlers.registerReturnValueHandler(new HttpEntityMethodProcessor(messageConverters));
|
||||
|
||||
// Default handler
|
||||
returnValueHandlers.registerReturnValueHandler(new DefaultMethodReturnValueHandler(customModelAndViewResolvers));
|
||||
returnValueHandlers.registerReturnValueHandler(new DefaultMethodReturnValueHandler(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find an {@link ExceptionHandler}-annotated method that can handle the thrown exception.
|
||||
* The exception-handling method, if found, is invoked resulting in a {@link ModelAndView}.
|
||||
* @return a {@link ModelAndView} if a matching exception-handling method was found, or {@code null} otherwise
|
||||
*/
|
||||
@Override
|
||||
protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@@ -226,13 +212,25 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
exceptionHandler.setHandlerMethodReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
ServletWebRequest webRequest = new ServletWebRequest(request, response);
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking exception-handling method: " + exceptionHandler);
|
||||
}
|
||||
ModelAndView mav = exceptionHandler.invokeAndHandle(webRequest , model , ex);
|
||||
return (mav != null) ? mav : new ModelAndView();
|
||||
|
||||
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
|
||||
exceptionHandler.invokeAndHandle(webRequest, mavContainer, ex);
|
||||
|
||||
if (!mavContainer.isResolveView()) {
|
||||
return new ModelAndView();
|
||||
}
|
||||
else {
|
||||
ModelAndView mav = new ModelAndView().addAllObjects(mavContainer.getModel());
|
||||
mav.setViewName(mavContainer.getViewName());
|
||||
if (mavContainer.getView() != null) {
|
||||
mav.setView((View) mavContainer.getView());
|
||||
}
|
||||
return mav;
|
||||
}
|
||||
}
|
||||
catch (Exception invocationEx) {
|
||||
logger.error("Invoking exception-handling method resulted in exception : " +
|
||||
@@ -244,6 +242,9 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an {@link ExceptionMethodMapping} for the the given handler method, never {@code null}
|
||||
*/
|
||||
private ExceptionMethodMapping getExceptionMethodMapping(HandlerMethod handlerMethod) {
|
||||
Class<?> handlerType = handlerMethod.getBeanType();
|
||||
ExceptionMethodMapping mapping = exceptionMethodMappingCache.get(handlerType);
|
||||
@@ -256,7 +257,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-built MethodFilter that matches {@link ExceptionHandler @ExceptionHandler} methods.
|
||||
* MethodFilter that matches {@link ExceptionHandler @ExceptionHandler} methods.
|
||||
*/
|
||||
public static MethodFilter EXCEPTION_HANDLER_METHODS = new MethodFilter() {
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} creates a Servlet data binder.
|
||||
* Creates a Servlet data binder.
|
||||
*/
|
||||
@Override
|
||||
protected WebDataBinder createBinderInstance(Object target, String objectName) {
|
||||
|
||||
@@ -20,23 +20,31 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.support.SessionStatus;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
|
||||
/**
|
||||
* Extends {@link InvocableHandlerMethod} with the ability to handle the return value of the invocation
|
||||
* resulting in a {@link ModelAndView} according to the {@link HandlerAdapter} contract.
|
||||
* Extends {@link InvocableHandlerMethod} with the ability to handle the return value through registered
|
||||
* {@link HandlerMethodArgumentResolver}s. If the handler method is annotated with {@link ResponseStatus},
|
||||
* the status on the response is set accordingly after method invocation but before return value handling.
|
||||
*
|
||||
* <p>Return value handling may be skipped entirely if the handler method returns a {@code null} (or is a
|
||||
* {@code void} method) and one of the following other conditions is true:
|
||||
* <ul>
|
||||
* <li>One of the {@link HandlerMethodArgumentResolver}s set the {@link ModelAndViewContainer#setResolveView(boolean)}
|
||||
* flag to {@code false}. This is the case when a method argument allows the handler method access to the response.
|
||||
* <li>The request qualifies as being not modified according to {@link ServletWebRequest#isNotModified()}.
|
||||
* This is used in conjunction with a "Last-Modified" header or ETag.
|
||||
* <li>The status on the response was set as a result of a {@link ResponseStatus} annotation
|
||||
* </ul>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
@@ -70,36 +78,47 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the method via {@link #invokeForRequest(NativeWebRequest, ModelMap, Object...)} and also handles the
|
||||
* return value by invoking one of the {@link HandlerMethodReturnValueHandler} instances registered via
|
||||
* {@link #setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite)}.
|
||||
* If the method is annotated with {@link SessionStatus} the response status will be set.
|
||||
* Invokes the method and handles the return value through registered {@link HandlerMethodReturnValueHandler}s.
|
||||
* If the handler method is annotated with {@link ResponseStatus}, the status on the response is set accordingly
|
||||
* after method invocation but before return value handling.
|
||||
* <p>Return value handling may be skipped entirely if the handler method returns a {@code null} (or is a
|
||||
* {@code void} method) and one of the following other conditions is true:
|
||||
* <ul>
|
||||
* <li>One of the {@link HandlerMethodArgumentResolver}s set the {@link ModelAndViewContainer#setResolveView(boolean)}
|
||||
* flag to {@code false}. This is the case when a method argument allows the handler method access to the response.
|
||||
* <li>The request qualifies as being not modified according to {@link ServletWebRequest#isNotModified()}.
|
||||
* This is used in conjunction with a "Last-Modified" header or ETag.
|
||||
* <li>The status on the response was set as a result of a {@link ResponseStatus} annotation
|
||||
* </ul>
|
||||
* <p>After the call, use the {@link ModelAndViewContainer} parameter to access model attributes and view selection
|
||||
* and to determine if view resolution is needed.
|
||||
*
|
||||
* @param request the current request
|
||||
* @param model the model used throughout the current request
|
||||
* @param providedArgs argument values to use as-is if they match to a method parameter's type
|
||||
* @return ModelAndView object with the name of the view and the required model data, or <code>null</code>
|
||||
* if the response was handled
|
||||
* @param mavContainer the {@link ModelAndViewContainer} for the current request
|
||||
* @param providedArgs argument values to try to use without the need for view resolution
|
||||
*/
|
||||
public final ModelAndView invokeAndHandle(NativeWebRequest request,
|
||||
ModelMap model,
|
||||
Object... providedArgs) throws Exception {
|
||||
|
||||
public final void invokeAndHandle(NativeWebRequest request,
|
||||
ModelAndViewContainer mavContainer,
|
||||
Object...providedArgs) throws Exception {
|
||||
|
||||
if (!returnValueHandlers.supportsReturnType(getReturnType())) {
|
||||
throw new IllegalStateException("No suitable HandlerMethodReturnValueHandler for method " + toString());
|
||||
}
|
||||
|
||||
Object returnValue = invokeForRequest(request, model, providedArgs);
|
||||
Object returnValue = invokeForRequest(request, mavContainer, providedArgs);
|
||||
|
||||
setResponseStatus((ServletWebRequest) request);
|
||||
|
||||
if (returnValue == null && (isRequestNotModified(request) || usesResponseArgument())) {
|
||||
return null;
|
||||
if (returnValue == null) {
|
||||
if (isRequestNotModified(request) || hasResponseStatus() || !mavContainer.isResolveView()) {
|
||||
mavContainer.setResolveView(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ModelAndViewContainer mavContainer = new ModelAndViewContainer(model);
|
||||
returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);
|
||||
mavContainer.setResolveView(true);
|
||||
|
||||
return getModelAndView(request, mavContainer, returnValue);
|
||||
returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,38 +139,17 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ModelAndView} from a {@link ModelAndViewContainer}.
|
||||
* Does the request qualify as not modified?
|
||||
*/
|
||||
private ModelAndView getModelAndView(NativeWebRequest request,
|
||||
ModelAndViewContainer mavContainer,
|
||||
Object returnValue) {
|
||||
if (returnValueHandlerUsesResponseArgument()) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
ModelAndView mav = new ModelAndView().addAllObjects(mavContainer.getModel());
|
||||
mav.setViewName(mavContainer.getViewName());
|
||||
if (mavContainer.getView() != null) {
|
||||
mav.setView((View) mavContainer.getView());
|
||||
}
|
||||
return mav;
|
||||
}
|
||||
private boolean isRequestNotModified(NativeWebRequest request) {
|
||||
return ((ServletWebRequest) request).isNotModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the request qualifies as not modified...
|
||||
* TODO: document fully including sample user code
|
||||
* Does the method set the response status?
|
||||
*/
|
||||
private boolean isRequestNotModified(NativeWebRequest request) {
|
||||
ServletWebRequest servletRequest = (ServletWebRequest) request;
|
||||
return (servletRequest.isNotModified() || (responseStatus != null) || usesResponseArgument());
|
||||
}
|
||||
|
||||
protected boolean usesResponseArgument() {
|
||||
return (super.usesResponseArgument() || returnValueHandlerUsesResponseArgument() || (responseStatus != null));
|
||||
private boolean hasResponseStatus() {
|
||||
return responseStatus != null;
|
||||
}
|
||||
|
||||
private boolean returnValueHandlerUsesResponseArgument() {
|
||||
return returnValueHandlers.usesResponseArgument(getReturnType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
|
||||
if (mav != ModelAndViewResolver.UNRESOLVED) {
|
||||
mavContainer.setView(mav.getView());
|
||||
mavContainer.setViewName(mav.getViewName());
|
||||
mavContainer.addModelAttributes(mav.getModel());
|
||||
mavContainer.addAllAttributes(mav.getModel());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
|
||||
}
|
||||
else if (!BeanUtils.isSimpleProperty(returnValue.getClass())) {
|
||||
String name = ModelFactory.getNameForReturnValue(returnValue, returnType);
|
||||
mavContainer.addModelAttribute(name, returnValue);
|
||||
mavContainer.addAttribute(name, returnValue);
|
||||
}
|
||||
|
||||
// should not happen
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.http.server.ServletServerHttpResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
@@ -74,7 +73,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
}
|
||||
|
||||
public Object resolveArgument(MethodParameter parameter,
|
||||
ModelMap model,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory)
|
||||
throws IOException, HttpMediaTypeNotSupportedException {
|
||||
@@ -116,19 +115,25 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws Exception {
|
||||
mavContainer.setResolveView(false);
|
||||
|
||||
if (returnValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HttpOutputMessage outputMessage = createOutputMessage(webRequest);
|
||||
|
||||
Assert.isInstanceOf(HttpEntity.class, returnValue);
|
||||
HttpEntity<?> responseEntity = (HttpEntity<?>) returnValue;
|
||||
HttpOutputMessage outputMessage = createOutputMessage(webRequest);
|
||||
if (responseEntity instanceof ResponseEntity) {
|
||||
((ServerHttpResponse) outputMessage).setStatusCode(((ResponseEntity<?>) responseEntity).getStatusCode());
|
||||
}
|
||||
|
||||
HttpHeaders entityHeaders = responseEntity.getHeaders();
|
||||
if (!entityHeaders.isEmpty()) {
|
||||
outputMessage.getHeaders().putAll(entityHeaders);
|
||||
}
|
||||
|
||||
Object body = responseEntity.getBody();
|
||||
if (body != null) {
|
||||
writeWithMessageConverters(body, createInputMessage(webRequest), outputMessage);
|
||||
|
||||
@@ -46,10 +46,10 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
|
||||
ModelAndView mav = (ModelAndView) returnValue;
|
||||
mavContainer.setView(mav.getView());
|
||||
mavContainer.setViewName(mav.getViewName());
|
||||
mavContainer.addModelAttributes(mav.getModel());
|
||||
mavContainer.addAllAttributes(mav.getModel());
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
mavContainer.setResolveView(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.http.server.ServletServerHttpResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -66,7 +65,7 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||
}
|
||||
|
||||
public Object resolveArgument(MethodParameter parameter,
|
||||
ModelMap model,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory)
|
||||
throws IOException, HttpMediaTypeNotSupportedException {
|
||||
@@ -82,8 +81,8 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||
public void handleReturnValue(Object returnValue,
|
||||
MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest)
|
||||
throws IOException, HttpMediaTypeNotAcceptableException {
|
||||
NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException {
|
||||
mavContainer.setResolveView(false);
|
||||
if (returnValue != null) {
|
||||
writeWithMessageConverters(webRequest, returnValue);
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.multipart.MultipartRequest;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
|
||||
}
|
||||
|
||||
public Object resolveArgument(MethodParameter parameter,
|
||||
ModelMap model,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws IOException {
|
||||
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
|
||||
|
||||
@@ -24,10 +24,10 @@ import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HandlerMethodArgumentResolver} that supports {@link ServletResponse} and related arguments.
|
||||
@@ -47,12 +47,14 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
|
||||
}
|
||||
|
||||
public Object resolveArgument(MethodParameter parameter,
|
||||
ModelMap model,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws IOException {
|
||||
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
|
||||
Class<?> parameterType = parameter.getParameterType();
|
||||
|
||||
mavContainer.setResolveView(false);
|
||||
|
||||
if (ServletResponse.class.isAssignableFrom(parameterType)) {
|
||||
Object nativeResponse = webRequest.getNativeResponse(parameterType);
|
||||
if (nativeResponse == null) {
|
||||
@@ -67,7 +69,9 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
|
||||
else if (Writer.class.isAssignableFrom(parameterType)) {
|
||||
return response.getWriter();
|
||||
}
|
||||
// should not happen
|
||||
throw new UnsupportedOperationException();
|
||||
else {
|
||||
// should not happen
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user