SPR-6464 Polish following code review.
This commit is contained in:
@@ -17,10 +17,10 @@
|
||||
package org.springframework.web.servlet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A FlashMap provides a way for one request to store attributes intended for
|
||||
@@ -35,7 +35,7 @@ import org.springframework.beans.BeanUtils;
|
||||
* recipient. On a redirect, the target URL is known and for example
|
||||
* {@code org.springframework.web.servlet.view.RedirectView} has the
|
||||
* opportunity to automatically update the current FlashMap with target
|
||||
* URL information .
|
||||
* URL information.
|
||||
*
|
||||
* <p>Annotated controllers will usually not use this type directly.
|
||||
* See {@code org.springframework.web.servlet.mvc.support.RedirectAttributes}
|
||||
@@ -46,13 +46,13 @@ import org.springframework.beans.BeanUtils;
|
||||
*
|
||||
* @see FlashMapManager
|
||||
*/
|
||||
public class FlashMap extends HashMap<String, Object> implements Comparable<FlashMap> {
|
||||
public final class FlashMap extends HashMap<String, Object> implements Comparable<FlashMap> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String targetRequestPath;
|
||||
|
||||
private final Map<String, String> targetRequestParams = new LinkedHashMap<String, String>();
|
||||
private final MultiValueMap<String, String> targetRequestParams = new LinkedMultiValueMap<String, String>();
|
||||
|
||||
private long expirationStartTime;
|
||||
|
||||
@@ -93,17 +93,15 @@ public class FlashMap extends HashMap<String, Object> implements Comparable<Flas
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide request parameter pairs to identify the request for this FlashMap.
|
||||
* Only simple type, non-null parameter values are used.
|
||||
* Provide request parameters identifying the request for this FlashMap.
|
||||
* Null or empty keys and values are skipped.
|
||||
* @param params a Map with the names and values of expected parameters.
|
||||
* @see BeanUtils#isSimpleValueType(Class)
|
||||
*/
|
||||
public FlashMap addTargetRequestParams(Map<String, ?> params) {
|
||||
public FlashMap addTargetRequestParams(MultiValueMap<String, String> params) {
|
||||
if (params != null) {
|
||||
for (String name : params.keySet()) {
|
||||
Object value = params.get(name);
|
||||
if ((value != null) && BeanUtils.isSimpleValueType(value.getClass())) {
|
||||
this.targetRequestParams.put(name, value.toString());
|
||||
for (String key : params.keySet()) {
|
||||
for (String value : params.get(key)) {
|
||||
addTargetRequestParam(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,19 +109,21 @@ public class FlashMap extends HashMap<String, Object> implements Comparable<Flas
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a request parameter to identify the request for this FlashMap.
|
||||
* @param name the name of the expected parameter, never {@code null}
|
||||
* @param value the value for the expected parameter, never {@code null}
|
||||
* Provide a request parameter identifying the request for this FlashMap.
|
||||
* @param name the expected parameter name, skipped if {@code null}
|
||||
* @param value the expected parameter value, skipped if {@code null}
|
||||
*/
|
||||
public FlashMap addTargetRequestParam(String name, String value) {
|
||||
this.targetRequestParams.put(name, value.toString());
|
||||
if (StringUtils.hasText(name) && StringUtils.hasText(value)) {
|
||||
this.targetRequestParams.add(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parameters identifying the target request, or an empty Map.
|
||||
* Return the parameters identifying the target request, or an empty map.
|
||||
*/
|
||||
public Map<String, String> getTargetRequestParams() {
|
||||
public MultiValueMap<String, String> getTargetRequestParams() {
|
||||
return targetRequestParams;
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@ public class FlashMap extends HashMap<String, Object> implements Comparable<Flas
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("[Attributes=").append(super.toString());
|
||||
result.append(", targetRequestPath=").append(this.targetRequestPath);
|
||||
result.append(", targetRequestParams=" + this.targetRequestParams.toString()).append("]");
|
||||
return result.toString();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[Attributes=").append(super.toString());
|
||||
sb.append(", targetRequestPath=").append(this.targetRequestPath);
|
||||
sb.append(", targetRequestParams=").append(this.targetRequestParams).append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
* instances are exposed as request attributes and are accessible via methods
|
||||
* in {@code org.springframework.web.servlet.support.RequestContextUtils}.
|
||||
*
|
||||
* <p>Annotated controllers are most likely to store and access flash attributes
|
||||
* through their model.
|
||||
* <p>Annotated controllers will usually not use this FlashMap directly.
|
||||
* See {@code org.springframework.web.servlet.mvc.support.RedirectAttributes}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
|
||||
@@ -130,6 +130,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
methodAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
methodAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
|
||||
methodAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
|
||||
methodAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", true);
|
||||
if (argumentResolvers != null) {
|
||||
methodAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
|
||||
}
|
||||
|
||||
@@ -73,42 +73,59 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* A base class that provides default configuration for Spring MVC applications by registering Spring MVC
|
||||
* infrastructure components to be detected by the {@link DispatcherServlet}. Typically applications should not
|
||||
* have to extend this class. A more likely place to start is to annotate an @{@link Configuration}
|
||||
* class with @{@link EnableWebMvc} (see @{@link EnableWebMvc} and {@link WebMvcConfigurer} for details).
|
||||
* A base class that provides default configuration for Spring MVC applications
|
||||
* by registering Spring MVC infrastructure components to be detected by the
|
||||
* {@link DispatcherServlet}. An application configuration class is not required
|
||||
* to extend this class. A more likely place to start is to annotate
|
||||
* an @{@link Configuration} class with @{@link EnableWebMvc}
|
||||
* (see @{@link EnableWebMvc} and {@link WebMvcConfigurer} for details).
|
||||
*
|
||||
* <p>If using @{@link EnableWebMvc} does not give you all you need, consider extending directly from this
|
||||
* class. Remember to add @{@link Configuration} to your subclass and @{@link Bean} to any superclass
|
||||
* @{@link Bean} methods you choose to override.
|
||||
* <p>If the customization options available with use of @{@link EnableWebMvc}
|
||||
* are not enough, consider extending directly from this class and override the
|
||||
* appropriate methods. Remember to add @{@link Configuration} to your subclass
|
||||
* and @{@link Bean} to any superclass @{@link Bean} methods you override.
|
||||
*
|
||||
* <p>This class registers the following {@link HandlerMapping}s:</p>
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controller methods.
|
||||
* <li>{@link HandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||
* <li>{@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||
* <li>{@link HandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||
* <li>{@link HandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||
* <li>{@link RequestMappingHandlerMapping}
|
||||
* ordered at 0 for mapping requests to annotated controller methods.
|
||||
* <li>{@link HandlerMapping}
|
||||
* ordered at 1 to map URL paths directly to view names.
|
||||
* <li>{@link BeanNameUrlHandlerMapping}
|
||||
* ordered at 2 to map URL paths to controller bean names.
|
||||
* <li>{@link HandlerMapping}
|
||||
* ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||
* <li>{@link HandlerMapping}
|
||||
* ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers these {@link HandlerAdapter}s:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerAdapter} for processing requests with annotated controller methods.
|
||||
* <li>{@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||
* <li>{@link SimpleControllerHandlerAdapter} for processing requests with interface-based {@link Controller}s.
|
||||
* <li>{@link RequestMappingHandlerAdapter}
|
||||
* for processing requests with annotated controller methods.
|
||||
* <li>{@link HttpRequestHandlerAdapter}
|
||||
* for processing requests with {@link HttpRequestHandler}s.
|
||||
* <li>{@link SimpleControllerHandlerAdapter}
|
||||
* for processing requests with interface-based {@link Controller}s.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of exception resolvers:
|
||||
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of
|
||||
* exception resolvers:
|
||||
* <ul>
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions
|
||||
* through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated
|
||||
* with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring
|
||||
* exception types
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers these other instances:
|
||||
* <ul>
|
||||
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
||||
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
||||
* <li>{@link FormattingConversionService}
|
||||
* for use with annotated controller methods and the spring:eval JSP tag.
|
||||
* <li>{@link Validator}
|
||||
* for validating model attributes on annotated controller methods.
|
||||
* </ul>
|
||||
*
|
||||
* @see EnableWebMvc
|
||||
@@ -137,7 +154,8 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controllers.
|
||||
* Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping
|
||||
* requests to annotated controllers.
|
||||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
@@ -148,8 +166,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the shared handler interceptors used to configure {@link HandlerMapping} instances with.
|
||||
* This method cannot be overridden, use {@link #addInterceptors(InterceptorRegistry)} instead.
|
||||
* Provide access to the shared handler interceptors used to configure
|
||||
* {@link HandlerMapping} instances with. This method cannot be overridden,
|
||||
* use {@link #addInterceptors(InterceptorRegistry)} instead.
|
||||
*/
|
||||
protected final Object[] getInterceptors() {
|
||||
if (interceptors == null) {
|
||||
@@ -162,15 +181,17 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to add Spring MVC interceptors for pre/post-processing of controller invocation.
|
||||
* Override this method to add Spring MVC interceptors for
|
||||
* pre- and post-processing of controller invocation.
|
||||
* @see InterceptorRegistry
|
||||
*/
|
||||
protected void addInterceptors(InterceptorRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler mapping ordered at 1 to map URL paths directly to view names.
|
||||
* To configure view controllers, override {@link #addViewControllers(ViewControllerRegistry)}.
|
||||
* Return a handler mapping ordered at 1 to map URL paths directly to
|
||||
* view names. To configure view controllers, override
|
||||
* {@link #addViewControllers}.
|
||||
*/
|
||||
@Bean
|
||||
public HandlerMapping viewControllerHandlerMapping() {
|
||||
@@ -191,7 +212,8 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||
* Return a {@link BeanNameUrlHandlerMapping} ordered at 2 to map URL
|
||||
* paths to controller bean names.
|
||||
*/
|
||||
@Bean
|
||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||
@@ -202,8 +224,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler mapping ordered at Integer.MAX_VALUE-1 with mapped resource handlers.
|
||||
* To configure resource handling, override {@link #addResourceHandlers(ResourceHandlerRegistry)}.
|
||||
* Return a handler mapping ordered at Integer.MAX_VALUE-1 with mapped
|
||||
* resource handlers. To configure resource handling, override
|
||||
* {@link #addResourceHandlers}.
|
||||
*/
|
||||
@Bean
|
||||
public HandlerMapping resourceHandlerMapping() {
|
||||
@@ -222,9 +245,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler mapping ordered at Integer.MAX_VALUE with a mapped default servlet handler.
|
||||
* To configure "default" Servlet handling, override
|
||||
* {@link #configureDefaultServletHandling(DefaultServletHandlerConfigurer)}.
|
||||
* Return a handler mapping ordered at Integer.MAX_VALUE with a mapped
|
||||
* default servlet handler. To configure "default" Servlet handling,
|
||||
* override {@link #configureDefaultServletHandling}.
|
||||
*/
|
||||
@Bean
|
||||
public HandlerMapping defaultServletHandlerMapping() {
|
||||
@@ -243,12 +266,13 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RequestMappingHandlerAdapter} for processing requests through annotated controller methods.
|
||||
* Consider overriding one of these other more fine-grained methods:
|
||||
* Returns a {@link RequestMappingHandlerAdapter} for processing requests
|
||||
* through annotated controller methods. Consider overriding one of these
|
||||
* other more fine-grained methods:
|
||||
* <ul>
|
||||
* <li>{@link #addArgumentResolvers(List)} for adding custom argument resolvers.
|
||||
* <li>{@link #addReturnValueHandlers(List)} for adding custom return value handlers.
|
||||
* <li>{@link #configureMessageConverters(List)} for adding custom message converters.
|
||||
* <li>{@link #addArgumentResolvers} for adding custom argument resolvers.
|
||||
* <li>{@link #addReturnValueHandlers} for adding custom return value handlers.
|
||||
* <li>{@link #configureMessageConverters} for adding custom message converters.
|
||||
* </ul>
|
||||
*/
|
||||
@Bean
|
||||
@@ -268,34 +292,46 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
adapter.setWebBindingInitializer(webBindingInitializer);
|
||||
adapter.setCustomArgumentResolvers(argumentResolvers);
|
||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||
adapter.setIgnoreDefaultModelOnRedirect(true);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to the ones registered by default.
|
||||
* <p>Custom argument resolvers are invoked before built-in resolvers except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @RequestParameter}, {@code @PathVariable}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param argumentResolvers the list of custom converters; initially an empty list.
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to
|
||||
* the ones registered by default.
|
||||
* <p>Custom argument resolvers are invoked before built-in resolvers
|
||||
* except for those that rely on the presence of annotations (e.g.
|
||||
* {@code @RequestParameter}, {@code @PathVariable}, etc.).
|
||||
* The latter can be customized by configuring the
|
||||
* {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param argumentResolvers the list of custom converters;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s in addition to the ones registered by default.
|
||||
* <p>Custom return value handlers are invoked before built-in ones except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param returnValueHandlers the list of custom handlers; initially an empty list.
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s in addition to the
|
||||
* ones registered by default.
|
||||
* <p>Custom return value handlers are invoked before built-in ones except
|
||||
* for those that rely on the presence of annotations (e.g.
|
||||
* {@code @ResponseBody}, {@code @ModelAttribute}, etc.).
|
||||
* The latter can be customized by configuring the
|
||||
* {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param returnValueHandlers the list of custom handlers;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the shared {@link HttpMessageConverter}s used by the
|
||||
* {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* This method cannot be overridden. Use {@link #configureMessageConverters(List)} instead.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} that can be used to add default message converters.
|
||||
* {@link RequestMappingHandlerAdapter} and the
|
||||
* {@link ExceptionHandlerExceptionResolver}.
|
||||
* This method cannot be overridden.
|
||||
* Use {@link #configureMessageConverters(List)} instead.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} that can be
|
||||
* used to add default message converters.
|
||||
*/
|
||||
protected final List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
if (messageConverters == null) {
|
||||
@@ -309,17 +345,20 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to add custom {@link HttpMessageConverter}s to use with
|
||||
* the {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* Adding converters to the list turns off the default converters that would otherwise be registered by default.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} that can be used to add default message converters.
|
||||
* @param converters a list to add message converters to; initially an empty list.
|
||||
* Override this method to add custom {@link HttpMessageConverter}s to use
|
||||
* with the {@link RequestMappingHandlerAdapter} and the
|
||||
* {@link ExceptionHandlerExceptionResolver}. Adding converters to the
|
||||
* list turns off the default converters that would otherwise be registered
|
||||
* by default. Also see {@link #addDefaultHttpMessageConverters(List)} that
|
||||
* can be used to add default message converters.
|
||||
* @param converters a list to add message converters to;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A method available to subclasses to add default {@link HttpMessageConverter}s.
|
||||
* Override this method to add default {@link HttpMessageConverter}s.
|
||||
* @param messageConverters the list to add the default message converters to
|
||||
*/
|
||||
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
@@ -346,9 +385,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link FormattingConversionService} for use with annotated controller methods and the
|
||||
* {@code spring:eval} JSP tag. Also see {@link #addFormatters(FormatterRegistry)} as an alternative
|
||||
* to overriding this method.
|
||||
* Returns a {@link FormattingConversionService} for use with annotated
|
||||
* controller methods and the {@code spring:eval} JSP tag.
|
||||
* Also see {@link #addFormatters} as an alternative to overriding this method.
|
||||
*/
|
||||
@Bean
|
||||
public FormattingConversionService mvcConversionService() {
|
||||
@@ -364,8 +403,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link Validator} for validating {@code @ModelAttribute} and {@code @RequestBody} arguments of
|
||||
* annotated controller methods. To configure a custom validation, override {@link #getValidator()}.
|
||||
* Returns {@link Validator} for validating {@code @ModelAttribute}
|
||||
* and {@code @RequestBody} arguments of annotated controller methods.
|
||||
* To configure a custom validation, override {@link #getValidator()}.
|
||||
*/
|
||||
@Bean
|
||||
Validator mvcValidator() {
|
||||
@@ -404,7 +444,8 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||
* Returns a {@link HttpRequestHandlerAdapter} for processing requests
|
||||
* with {@link HttpRequestHandler}s.
|
||||
*/
|
||||
@Bean
|
||||
public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||
@@ -412,7 +453,8 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleControllerHandlerAdapter} for processing requests with interface-based controllers.
|
||||
* Returns a {@link SimpleControllerHandlerAdapter} for processing requests
|
||||
* with interface-based controllers.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||
@@ -420,8 +462,9 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HandlerExceptionResolverComposite} that contains a list of exception resolvers.
|
||||
* To customize the list of exception resolvers, override {@link #configureHandlerExceptionResolvers(List)}.
|
||||
* Returns a {@link HandlerExceptionResolverComposite} that contains a list
|
||||
* of exception resolvers. To customize the list of exception resolvers,
|
||||
* override {@link #configureHandlerExceptionResolvers(List)}.
|
||||
*/
|
||||
@Bean
|
||||
HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||
@@ -439,21 +482,28 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure the list of {@link HandlerExceptionResolver}s to use.
|
||||
* Adding resolvers to the list turns off the default resolvers that would otherwise be registered by default.
|
||||
* Also see {@link #addDefaultHandlerExceptionResolvers(List)} that can be used to add the default exception resolvers.
|
||||
* @param exceptionResolvers a list to add exception resolvers to; initially an empty list.
|
||||
* Override this method to configure the list of
|
||||
* {@link HandlerExceptionResolver}s to use. Adding resolvers to the list
|
||||
* turns off the default resolvers that would otherwise be registered by
|
||||
* default. Also see {@link #addDefaultHandlerExceptionResolvers(List)}
|
||||
* that can be used to add the default exception resolvers.
|
||||
* @param exceptionResolvers a list to add exception resolvers to;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A method available to subclasses for adding default {@link HandlerExceptionResolver}s.
|
||||
* A method available to subclasses for adding default
|
||||
* {@link HandlerExceptionResolver}s.
|
||||
* <p>Adds the following exception resolvers:
|
||||
* <ul>
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* <li>{@link ExceptionHandlerExceptionResolver}
|
||||
* for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver}
|
||||
* for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver}
|
||||
* for resolving known Spring exception types
|
||||
* </ul>
|
||||
*/
|
||||
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
|
||||
@@ -235,7 +235,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!mavContainer.isResolveView()) {
|
||||
if (mavContainer.isRequestHandled()) {
|
||||
return new ModelAndView();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -93,7 +93,6 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequ
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
@@ -147,7 +146,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
|
||||
private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
|
||||
|
||||
private boolean alwaysUseRedirectAttributes;
|
||||
private boolean ignoreDefaultModelOnRedirect = false;
|
||||
|
||||
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache =
|
||||
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>();
|
||||
@@ -334,19 +333,20 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
}
|
||||
|
||||
/**
|
||||
* By default a controller uses {@link Model} to select attributes for
|
||||
* rendering and for redirecting. However, a controller can also use
|
||||
* {@link RedirectAttributes} to select attributes before a redirect.
|
||||
* <p>When this flag is set to {@code true}, {@link RedirectAttributes}
|
||||
* becomes the only way to select attributes for a redirect.
|
||||
* In other words, for a redirect a controller must use
|
||||
* {@link RedirectAttributes} or no attributes will be used.
|
||||
* <p>The default value is {@code false}, meaning the {@link Model} is
|
||||
* used unless {@link RedirectAttributes} is used.
|
||||
* A controller can use the "default" {@link Model} in rendering and
|
||||
* redirect scenarios. Alternatively, it can use {@link RedirectAttributes}
|
||||
* to provide attributes for a redirect scenario.
|
||||
* <p>When this flag is set to {@code true}, the "default" model is never
|
||||
* used in a redirect even if the controller method doesn't explicitly
|
||||
* declare a RedirectAttributes argument.
|
||||
* <p>When set to {@code false}, the "default" model may be used in a
|
||||
* redirect if the controller method doesn't explicitly declare a
|
||||
* RedirectAttributes argument.
|
||||
* <p>The default setting is {@code false}.
|
||||
* @see RedirectAttributes
|
||||
*/
|
||||
public void setAlwaysUseRedirectAttributes(boolean alwaysUseRedirectAttributes) {
|
||||
this.alwaysUseRedirectAttributes = alwaysUseRedirectAttributes;
|
||||
public void setIgnoreDefaultModelOnRedirect(boolean ignoreDefaultModelOnRedirect) {
|
||||
this.ignoreDefaultModelOnRedirect = ignoreDefaultModelOnRedirect;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
@@ -538,18 +538,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
|
||||
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
|
||||
modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);
|
||||
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
|
||||
|
||||
if (this.alwaysUseRedirectAttributes) {
|
||||
DataBinder dataBinder = binderFactory.createBinder(webRequest, null, null);
|
||||
mavContainer.setRedirectModel(new RedirectAttributesModelMap(dataBinder));
|
||||
}
|
||||
|
||||
SessionStatus sessionStatus = new SimpleSessionStatus();
|
||||
|
||||
requestMappingMethod.invokeAndHandle(webRequest, mavContainer, sessionStatus);
|
||||
modelFactory.updateModel(webRequest, mavContainer, sessionStatus);
|
||||
|
||||
if (!mavContainer.isResolveView()) {
|
||||
if (mavContainer.isRequestHandled()) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||
* <p>Return value handling may be skipped entirely when the method returns {@code null} (also possibly due
|
||||
* to a {@code void} return type) and one of the following additional conditions is true:
|
||||
* <ul>
|
||||
* <li>A {@link HandlerMethodArgumentResolver} has set the {@link ModelAndViewContainer#setResolveView(boolean)}
|
||||
* <li>A {@link HandlerMethodArgumentResolver} has set the {@link ModelAndViewContainer#setRequestHandled(boolean)}
|
||||
* flag to {@code false} -- e.g. method arguments providing access to the response.
|
||||
* <li>The request qualifies as "not modified" as defined in {@link ServletWebRequest#checkNotModified(long)}
|
||||
* and {@link ServletWebRequest#checkNotModified(String)}. In this case a response with "not modified" response
|
||||
@@ -98,13 +98,13 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||
setResponseStatus((ServletWebRequest) request);
|
||||
|
||||
if (returnValue == null) {
|
||||
if (isRequestNotModified(request) || hasResponseStatus() || !mavContainer.isResolveView()) {
|
||||
mavContainer.setResolveView(false);
|
||||
if (isRequestNotModified(request) || hasResponseStatus() || mavContainer.isRequestHandled()) {
|
||||
mavContainer.setRequestHandled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mavContainer.setResolveView(true);
|
||||
mavContainer.setRequestHandled(false);
|
||||
|
||||
try {
|
||||
returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);
|
||||
|
||||
@@ -101,7 +101,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
mavContainer.setResolveView(false);
|
||||
mavContainer.setRequestHandled(true);
|
||||
|
||||
if (returnValue == null) {
|
||||
return;
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* Handles return values of type {@link ModelAndView} transferring their content to the {@link ModelAndViewContainer}.
|
||||
* If the return value is {@code null}, the {@link ModelAndViewContainer#setResolveView(boolean)} flag is set to
|
||||
* If the return value is {@code null}, the {@link ModelAndViewContainer#setRequestHandled(boolean)} flag is set to
|
||||
* {@code false} to indicate view resolution is not needed.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -49,7 +49,7 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
|
||||
mavContainer.addAllAttributes(mav.getModel());
|
||||
}
|
||||
else {
|
||||
mavContainer.setResolveView(false);
|
||||
mavContainer.setRequestHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,16 +49,10 @@ public class RedirectAttributesMethodArgumentResolver implements HandlerMethodAr
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws Exception {
|
||||
|
||||
if (mavContainer.getRedirectModel() != null) {
|
||||
return mavContainer.getRedirectModel();
|
||||
}
|
||||
else {
|
||||
DataBinder dataBinder = binderFactory.createBinder(webRequest, null, null);
|
||||
ModelMap redirectAttributes = new RedirectAttributesModelMap(dataBinder);
|
||||
mavContainer.setRedirectModel(redirectAttributes);
|
||||
return redirectAttributes;
|
||||
}
|
||||
DataBinder dataBinder = binderFactory.createBinder(webRequest, null, null);
|
||||
ModelMap redirectAttributes = new RedirectAttributesModelMap(dataBinder);
|
||||
mavContainer.setRedirectModel(redirectAttributes);
|
||||
return redirectAttributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||
MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException {
|
||||
mavContainer.setResolveView(false);
|
||||
mavContainer.setRequestHandled(true);
|
||||
if (returnValue != null) {
|
||||
writeWithMessageConverters(returnValue, returnType, webRequest);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Sets the {@link ModelAndViewContainer#setResolveView(boolean)} flag to {@code false} to indicate
|
||||
* <p>Sets the {@link ModelAndViewContainer#setRequestHandled(boolean)} flag to {@code false} to indicate
|
||||
* that the method signature provides access to the response. If subsequently the underlying method
|
||||
* returns {@code null}, view resolution will be bypassed.
|
||||
* @see ServletInvocableHandlerMethod#invokeAndHandle(NativeWebRequest, ModelAndViewContainer, Object...)
|
||||
@@ -64,7 +64,7 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws IOException {
|
||||
|
||||
mavContainer.setResolveView(false);
|
||||
mavContainer.setRequestHandled(true);
|
||||
|
||||
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
|
||||
Class<?> paramType = parameter.getParameterType();
|
||||
|
||||
@@ -61,14 +61,14 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan
|
||||
String viewName = (String) returnValue;
|
||||
mavContainer.setViewName(viewName);
|
||||
if (isRedirectViewName(viewName)) {
|
||||
mavContainer.setUseRedirectModel();
|
||||
mavContainer.setUseRedirectModel(true);
|
||||
}
|
||||
}
|
||||
else if (returnValue instanceof View){
|
||||
View view = (View) returnValue;
|
||||
mavContainer.setView(view);
|
||||
if (isRedirectView(view)) {
|
||||
mavContainer.setUseRedirectModel();
|
||||
mavContainer.setUseRedirectModel(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -95,7 +95,7 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan
|
||||
* "false" otherwise.
|
||||
*/
|
||||
protected boolean isRedirectView(View view) {
|
||||
if (SmartView.class.isAssignableFrom(view.getClass())) {
|
||||
if (view instanceof SmartView) {
|
||||
return ((SmartView) view).isRedirectView();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -27,13 +27,14 @@ import javax.servlet.http.HttpSession;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.servlet.FlashMapManager;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* A default {@link FlashMapManager} implementation keeps {@link FlashMap}
|
||||
* A default {@link FlashMapManager} implementation that stores {@link FlashMap}
|
||||
* instances in the HTTP session.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -122,9 +123,10 @@ public class DefaultFlashMapManager implements FlashMapManager {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (flashMap.getTargetRequestParams() != null) {
|
||||
for (String paramName : flashMap.getTargetRequestParams().keySet()) {
|
||||
if (!flashMap.getTargetRequestParams().get(paramName).equals(request.getParameter(paramName))) {
|
||||
MultiValueMap<String, String> params = flashMap.getTargetRequestParams();
|
||||
for (String key : params.keySet()) {
|
||||
for (String value : params.get(key)) {
|
||||
if (!value.equals(request.getParameter(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.SmartView;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
@@ -240,11 +242,9 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
|
||||
|
||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
|
||||
if (!CollectionUtils.isEmpty(flashMap)) {
|
||||
String targetPath = WebUtils.extractUrlPath(targetUrl.toString());
|
||||
flashMap.setTargetRequestPath(targetPath);
|
||||
if (this.exposeModelAttributes) {
|
||||
flashMap.addTargetRequestParams(model);
|
||||
}
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build();
|
||||
flashMap.setTargetRequestPath(uriComponents.getPath());
|
||||
flashMap.addTargetRequestParams(uriComponents.getQueryParams());
|
||||
}
|
||||
|
||||
sendRedirect(request, response, targetUrl.toString(), this.http10Compatible);
|
||||
|
||||
Reference in New Issue
Block a user