1
1
/*
2
- * Copyright 2002-2014 the original author or authors.
2
+ * Copyright 2002-2015 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
59
59
import org .springframework .web .util .WebUtils ;
60
60
61
61
/**
62
- * Central dispatcher for HTTP request handlers/controllers, e.g. for web UI controllers or HTTP-based remote service
63
- * exporters. Dispatches to registered handlers for processing a web request, providing convenient mapping and exception
64
- * handling facilities.
62
+ * Central dispatcher for HTTP request handlers/controllers, e.g. for web UI controllers
63
+ * or HTTP-based remote service exporters. Dispatches to registered handlers for processing
64
+ * a web request, providing convenient mapping and exception handling facilities.
65
65
*
66
- * <p>This servlet is very flexible: It can be used with just about any workflow, with the installation of the
67
- * appropriate adapter classes. It offers the following functionality that distinguishes it from other request-driven
68
- * web MVC frameworks:
66
+ * <p>This servlet is very flexible: It can be used with just about any workflow, with the
67
+ * installation of the appropriate adapter classes. It offers the following functionality
68
+ * that distinguishes it from other request-driven web MVC frameworks:
69
69
*
70
- * <ul> <li>It is based around a JavaBeans configuration mechanism.
70
+ * <ul>
71
+ * <li>It is based around a JavaBeans configuration mechanism.
71
72
*
72
- * <li>It can use any {@link HandlerMapping} implementation - pre-built or provided as part of an application - to
73
- * control the routing of requests to handler objects. Default is {@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping}
74
- * and {@link org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping}. HandlerMapping objects
75
- * can be defined as beans in the servlet's application context, implementing the HandlerMapping interface, overriding
76
- * the default HandlerMapping if present. HandlerMappings can be given any bean name (they are tested by type).
73
+ * <li>It can use any {@link HandlerMapping} implementation - pre-built or provided as part
74
+ * of an application - to control the routing of requests to handler objects. Default is
75
+ * {@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping} and
76
+ * {@link org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping}.
77
+ * HandlerMapping objects can be defined as beans in the servlet's application context,
78
+ * implementing the HandlerMapping interface, overriding the default HandlerMapping if
79
+ * present. HandlerMappings can be given any bean name (they are tested by type).
77
80
*
78
- * <li>It can use any {@link HandlerAdapter}; this allows for using any handler interface. Default adapters are {@link
79
- * org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter}, {@link org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter},
80
- * for Spring's {@link org.springframework.web.HttpRequestHandler} and {@link org.springframework.web.servlet.mvc.Controller}
81
- * interfaces, respectively. A default {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter}
82
- * will be registered as well. HandlerAdapter objects can be added as beans in the application context, overriding the
83
- * default HandlerAdapters. Like HandlerMappings, HandlerAdapters can be given any bean name (they are tested by type).
81
+ * <li>It can use any {@link HandlerAdapter}; this allows for using any handler interface.
82
+ * Default adapters are {@link org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter},
83
+ * {@link org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter}, for Spring's
84
+ * {@link org.springframework.web.HttpRequestHandler} and
85
+ * {@link org.springframework.web.servlet.mvc.Controller} interfaces, respectively. A default
86
+ * {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter}
87
+ * will be registered as well. HandlerAdapter objects can be added as beans in the
88
+ * application context, overriding the default HandlerAdapters. Like HandlerMappings,
89
+ * HandlerAdapters can be given any bean name (they are tested by type).
84
90
*
85
- * <li>The dispatcher's exception resolution strategy can be specified via a {@link HandlerExceptionResolver}, for
86
- * example mapping certain exceptions to error pages. Default are
91
+ * <li>The dispatcher's exception resolution strategy can be specified via a
92
+ * {@link HandlerExceptionResolver}, for example mapping certain exceptions to error pages.
93
+ * Default are
87
94
* {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver},
88
95
* {@link org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver}, and
89
- * {@link org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver}. These HandlerExceptionResolvers can be overridden
90
- * through the application context. HandlerExceptionResolver can be given any bean name (they are tested by type).
96
+ * {@link org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver}.
97
+ * These HandlerExceptionResolvers can be overridden through the application context.
98
+ * HandlerExceptionResolver can be given any bean name (they are tested by type).
91
99
*
92
- * <li>Its view resolution strategy can be specified via a {@link ViewResolver} implementation, resolving symbolic view
93
- * names into View objects. Default is {@link org.springframework.web.servlet.view.InternalResourceViewResolver}.
94
- * ViewResolver objects can be added as beans in the application context, overriding the default ViewResolver.
95
- * ViewResolvers can be given any bean name (they are tested by type).
100
+ * <li>Its view resolution strategy can be specified via a {@link ViewResolver}
101
+ * implementation, resolving symbolic view names into View objects. Default is
102
+ * {@link org.springframework.web.servlet.view.InternalResourceViewResolver}.
103
+ * ViewResolver objects can be added as beans in the application context, overriding the
104
+ * default ViewResolver. ViewResolvers can be given any bean name (they are tested by type).
96
105
*
97
- * <li>If a {@link View} or view name is not supplied by the user, then the configured {@link
98
- * RequestToViewNameTranslator} will translate the current request into a view name. The corresponding bean name is
99
- * "viewNameTranslator"; the default is {@link org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator}.
106
+ * <li>If a {@link View} or view name is not supplied by the user, then the configured
107
+ * {@link RequestToViewNameTranslator} will translate the current request into a view name.
108
+ * The corresponding bean name is "viewNameTranslator"; the default is
109
+ * {@link org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator}.
100
110
*
101
- * <li>The dispatcher's strategy for resolving multipart requests is determined by a {@link
102
- * org.springframework.web.multipart.MultipartResolver} implementation. Implementations for Jakarta Commons FileUpload
103
- * and Jason Hunter's COS are included; the typical choise is {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
111
+ * <li>The dispatcher's strategy for resolving multipart requests is determined by a
112
+ * {@link org.springframework.web.multipart.MultipartResolver} implementation.
113
+ * Implementations for Apache Commons FileUpload and Servlet 3 are included; the typical
114
+ * choice is {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
104
115
* The MultipartResolver bean name is "multipartResolver"; default is none.
105
116
*
106
- * <li>Its locale resolution strategy is determined by a {@link LocaleResolver}. Out-of-the-box implementations work via
107
- * HTTP accept header, cookie, or session. The LocaleResolver bean name is "localeResolver"; default is {@link
108
- * org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver}.
117
+ * <li>Its locale resolution strategy is determined by a {@link LocaleResolver}.
118
+ * Out-of-the-box implementations work via HTTP accept header, cookie, or session.
119
+ * The LocaleResolver bean name is "localeResolver"; default is
120
+ * {@link org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver}.
109
121
*
110
- * <li>Its theme resolution strategy is determined by a {@link ThemeResolver}. Implementations for a fixed theme and for
111
- * cookie and session storage are included. The ThemeResolver bean name is "themeResolver"; default is {@link
112
- * org.springframework.web.servlet.theme.FixedThemeResolver}. </ul>
122
+ * <li>Its theme resolution strategy is determined by a {@link ThemeResolver}.
123
+ * Implementations for a fixed theme and for cookie and session storage are included.
124
+ * The ThemeResolver bean name is "themeResolver"; default is
125
+ * {@link org.springframework.web.servlet.theme.FixedThemeResolver}.
126
+ * </ul>
113
127
*
114
- * <p><b>NOTE: The {@code @RequestMapping} annotation will only be processed if a corresponding
115
- * {@code HandlerMapping} (for type level annotations) and/or {@code HandlerAdapter} (for method level
116
- * annotations) is present in the dispatcher.</b> This is the case by default. However, if you are defining custom
117
- * {@code HandlerMappings} or {@code HandlerAdapters}, then you need to make sure that a corresponding custom
118
- * {@code DefaultAnnotationHandlerMapping} and/or {@code AnnotationMethodHandlerAdapter} is defined as well -
119
- * provided that you intend to use {@code @RequestMapping}.
128
+ * <p><b>NOTE: The {@code @RequestMapping} annotation will only be processed if a
129
+ * corresponding {@code HandlerMapping} (for type-level annotations) and/or
130
+ * {@code HandlerAdapter} (for method-level annotations) is present in the dispatcher.</b>
131
+ * This is the case by default. However, if you are defining custom {@code HandlerMappings}
132
+ * or {@code HandlerAdapters}, then you need to make sure that a corresponding custom
133
+ * {@code DefaultAnnotationHandlerMapping} and/or {@code AnnotationMethodHandlerAdapter}
134
+ * is defined as well - provided that you intend to use {@code @RequestMapping}.
120
135
*
121
- * <p><b>A web application can define any number of DispatcherServlets.</b> Each servlet will operate in its own
122
- * namespace, loading its own application context with mappings, handlers, etc. Only the root application context as
123
- * loaded by {@link org.springframework.web.context.ContextLoaderListener}, if any, will be shared.
136
+ * <p><b>A web application can define any number of DispatcherServlets.</b>
137
+ * Each servlet will operate in its own namespace, loading its own application context
138
+ * with mappings, handlers, etc. Only the root application context as loaded by
139
+ * {@link org.springframework.web.context.ContextLoaderListener}, if any, will be shared.
124
140
*
125
141
* <p>As of Spring 3.1, {@code DispatcherServlet} may now be injected with a web
126
142
* application context, rather than creating its own internally. This is useful in Servlet
127
- * 3.0+ environments, which support programmatic registration of servlet instances. See
128
- * {@link #DispatcherServlet(WebApplicationContext)} Javadoc for details.
143
+ * 3.0+ environments, which support programmatic registration of servlet instances.
144
+ * See the {@link #DispatcherServlet(WebApplicationContext)} javadoc for details.
129
145
*
130
146
* @author Rod Johnson
131
147
* @author Juergen Hoeller
@@ -851,12 +867,11 @@ protected void doService(HttpServletRequest request, HttpServletResponse respons
851
867
doDispatch (request , response );
852
868
}
853
869
finally {
854
- if (WebAsyncUtils .getAsyncManager (request ).isConcurrentHandlingStarted ()) {
855
- return ;
856
- }
857
- // Restore the original attribute snapshot, in case of an include.
858
- if (attributesSnapshot != null ) {
859
- restoreAttributesAfterInclude (request , attributesSnapshot );
870
+ if (!WebAsyncUtils .getAsyncManager (request ).isConcurrentHandlingStarted ()) {
871
+ // Restore the original attribute snapshot, in case of an include.
872
+ if (attributesSnapshot != null ) {
873
+ restoreAttributesAfterInclude (request , attributesSnapshot );
874
+ }
860
875
}
861
876
}
862
877
}
@@ -885,7 +900,7 @@ protected void doDispatch(HttpServletRequest request, HttpServletResponse respon
885
900
886
901
try {
887
902
processedRequest = checkMultipart (request );
888
- multipartRequestParsed = processedRequest != request ;
903
+ multipartRequestParsed = ( processedRequest != request ) ;
889
904
890
905
// Determine handler for the current request.
891
906
mappedHandler = getHandler (processedRequest , false );
@@ -914,14 +929,11 @@ protected void doDispatch(HttpServletRequest request, HttpServletResponse respon
914
929
return ;
915
930
}
916
931
917
- try {
918
- // Actually invoke the handler.
919
- mv = ha .handle (processedRequest , response , mappedHandler .getHandler ());
920
- }
921
- finally {
922
- if (asyncManager .isConcurrentHandlingStarted ()) {
923
- return ;
924
- }
932
+ // Actually invoke the handler.
933
+ mv = ha .handle (processedRequest , response , mappedHandler .getHandler ());
934
+
935
+ if (asyncManager .isConcurrentHandlingStarted ()) {
936
+ return ;
925
937
}
926
938
927
939
applyDefaultViewName (request , mv );
@@ -941,12 +953,15 @@ protected void doDispatch(HttpServletRequest request, HttpServletResponse respon
941
953
finally {
942
954
if (asyncManager .isConcurrentHandlingStarted ()) {
943
955
// Instead of postHandle and afterCompletion
944
- mappedHandler .applyAfterConcurrentHandlingStarted (processedRequest , response );
945
- return ;
956
+ if (mappedHandler != null ) {
957
+ mappedHandler .applyAfterConcurrentHandlingStarted (processedRequest , response );
958
+ }
946
959
}
947
- // Clean up any resources used by a multipart request.
948
- if (multipartRequestParsed ) {
949
- cleanupMultipart (processedRequest );
960
+ else {
961
+ // Clean up any resources used by a multipart request.
962
+ if (multipartRequestParsed ) {
963
+ cleanupMultipart (processedRequest );
964
+ }
950
965
}
951
966
}
952
967
}
@@ -1255,7 +1270,7 @@ private void triggerAfterCompletion(HttpServletRequest request, HttpServletRespo
1255
1270
}
1256
1271
1257
1272
private void triggerAfterCompletionWithError (HttpServletRequest request , HttpServletResponse response ,
1258
- HandlerExecutionChain mappedHandler , Error error ) throws Exception , ServletException {
1273
+ HandlerExecutionChain mappedHandler , Error error ) throws Exception {
1259
1274
1260
1275
ServletException ex = new NestedServletException ("Handler processing failed" , error );
1261
1276
if (mappedHandler != null ) {
0 commit comments