25
25
import javax .servlet .http .HttpServletRequest ;
26
26
import javax .servlet .http .HttpServletResponse ;
27
27
28
+ import org .springframework .web .context .request .async .WebAsyncManager ;
28
29
import org .springframework .web .context .request .async .WebAsyncUtils ;
29
30
30
31
/**
36
37
* as part of an {@linkplain javax.servlet.DispatcherType.ASYNC ASYNC} dispatch.
37
38
* Sub-classes may decide whether to be invoked once per request or once per
38
39
* request thread for as long as the same request is being processed.
39
- * See {@link #shouldFilterAsyncDispatches ()}.
40
+ * See {@link #shouldNotFilterAsyncDispatch ()}.
40
41
*
41
42
* <p>The {@link #getAlreadyFilteredAttributeName} method determines how
42
43
* to identify that a request is already filtered. The default implementation
@@ -73,12 +74,13 @@ public final void doFilter(ServletRequest request, ServletResponse response, Fil
73
74
HttpServletRequest httpRequest = (HttpServletRequest ) request ;
74
75
HttpServletResponse httpResponse = (HttpServletResponse ) response ;
75
76
76
- boolean processAsyncRequestThread = isAsyncDispatch (httpRequest ) && shouldFilterAsyncDispatches ();
77
+ WebAsyncManager asyncManager = WebAsyncUtils .getAsyncManager (request );
78
+ boolean processAsyncDispatch = asyncManager .hasConcurrentResult () && !shouldNotFilterAsyncDispatch ();
77
79
78
80
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName ();
79
81
boolean hasAlreadyFilteredAttribute = request .getAttribute (alreadyFilteredAttributeName ) != null ;
80
82
81
- if ((hasAlreadyFilteredAttribute && (!processAsyncRequestThread )) || shouldNotFilter (httpRequest )) {
83
+ if ((hasAlreadyFilteredAttribute && (!processAsyncDispatch )) || shouldNotFilter (httpRequest )) {
82
84
83
85
// Proceed without invoking this filter...
84
86
filterChain .doFilter (request , response );
@@ -90,7 +92,7 @@ public final void doFilter(ServletRequest request, ServletResponse response, Fil
90
92
doFilterInternal (httpRequest , httpResponse , filterChain );
91
93
}
92
94
finally {
93
- if (isLastRequestThread ( httpRequest )) {
95
+ if (! asyncManager . isConcurrentHandlingStarted ( )) {
94
96
// Remove the "already filtered" request attribute for this request.
95
97
request .removeAttribute (alreadyFilteredAttributeName );
96
98
}
@@ -128,60 +130,30 @@ protected boolean shouldNotFilter(HttpServletRequest request) throws ServletExce
128
130
}
129
131
130
132
/**
131
- * Whether to filter once per request or once per request thread. The dispatcher
132
- * type {@code javax.servlet.DispatcherType.ASYNC} introduced in Servlet 3.0
133
- * means a filter can be invoked in more than one thread (and exited) over the
134
- * course of a single request. Some filters only need to filter the initial
135
- * thread (e.g. request wrapping) while others may need to be invoked at least
136
- * once in each additional thread for example for setting up thread locals or
137
- * to perform final processing at the very end.
133
+ * Whether to filter async dispatches, which occur in a different thread.
134
+ * The dispatcher type {@code javax.servlet.DispatcherType.ASYNC} introduced
135
+ * in Servlet 3.0 means a filter can be invoked in more than one thread (and
136
+ * exited) over the course of a single request. Some filters only need to
137
+ * filter the initial thread (e.g. request wrapping) while others may need
138
+ * to be invoked at least once in each additional thread for example for
139
+ * setting up thread locals or to perform final processing at the very end.
138
140
* <p>Note that although a filter can be mapped to handle specific dispatcher
139
141
* types via {@code web.xml} or in Java through the {@code ServletContext},
140
- * servlet containers may enforce different defaults with regards to dispatcher
141
- * types. This flag enforces the design intent of the filter.
142
- * <p>The default setting is "false", which means the filter will be invoked
143
- * once only per request and only on the initial request thread. If "true", the
144
- * filter will also be invoked once only on each additional thread.
145
- *
146
- * @see org.springframework.web.context.request.async.WebAsyncManager
142
+ * servlet containers may enforce different defaults with regards to
143
+ * dispatcher types. This flag enforces the design intent of the filter.
144
+ * <p>The default setting is "true", which means the filter will not be
145
+ * invoked during subsequent async dispatches. If "false", the filter will
146
+ * be invoked during async dispatches with the same guarantees of being
147
+ * invoked only once during a request within a single thread.
147
148
*/
148
- protected boolean shouldFilterAsyncDispatches () {
149
- return false ;
150
- }
151
-
152
- /**
153
- * Whether the request was dispatched to complete processing of results produced
154
- * in another thread. This aligns with the Servlet 3.0 dispatcher type
155
- * {@code javax.servlet.DispatcherType.ASYNC} and can be used by filters that
156
- * return "true" from {@link #shouldFilterAsyncDispatches()} to detect when
157
- * the filter is being invoked subsequently in additional thread(s).
158
- *
159
- * @see org.springframework.web.context.request.async.WebAsyncManager
160
- */
161
- protected final boolean isAsyncDispatch (HttpServletRequest request ) {
162
- return WebAsyncUtils .getAsyncManager (request ).hasConcurrentResult ();
163
- }
164
-
165
- /**
166
- * Whether this is the last thread processing the request. Note the returned
167
- * value may change from {@code true} to {@code false} if the method is
168
- * invoked before and after delegating to the next filter, since the next filter
169
- * or servlet may begin concurrent processing. Therefore this method is most
170
- * useful after delegation for final, end-of-request type processing.
171
- * @param request the current request
172
- * @return {@code true} if the response will be committed when the current
173
- * thread exits; {@code false} if the response will remain open.
174
- *
175
- * @see org.springframework.web.context.request.async.WebAsyncManager
176
- */
177
- protected final boolean isLastRequestThread (HttpServletRequest request ) {
178
- return (!WebAsyncUtils .getAsyncManager (request ).isConcurrentHandlingStarted ());
149
+ protected boolean shouldNotFilterAsyncDispatch () {
150
+ return true ;
179
151
}
180
152
181
153
/**
182
154
* Same contract as for <code>doFilter</code>, but guaranteed to be
183
- * just invoked once per request or once per request thread.
184
- * See {@link #shouldFilterAsyncDispatches ()} for details.
155
+ * just invoked once per request within a single request thread.
156
+ * See {@link #shouldNotFilterAsyncDispatch ()} for details.
185
157
* <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
186
158
* default ServletRequest and ServletResponse ones.
187
159
*/
0 commit comments