View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.web.portlet;
18  
19  import javax.portlet.ActionRequest;
20  import javax.portlet.ActionResponse;
21  import javax.portlet.EventRequest;
22  import javax.portlet.EventResponse;
23  import javax.portlet.RenderRequest;
24  import javax.portlet.RenderResponse;
25  import javax.portlet.ResourceRequest;
26  import javax.portlet.ResourceResponse;
27  
28  /**
29   * Workflow interface that allows for customized handler execution chains.
30   * Applications can register any number of existing or custom interceptors
31   * for certain groups of handlers, to add common pre-processing behavior
32   * without needing to modify each handler implementation.
33   *
34   * <p>A {@code HandlerInterceptor} gets called before the appropriate
35   * {@link HandlerAdapter} triggers the
36   * execution of the handler itself. This mechanism can be used for a large
37   * field of preprocessing aspects, e.g. for authorization checks,
38   * or common handler behavior like locale or theme changes. Its main purpose
39   * is to permit the factoring out of otherwise repetitive handler code.
40   *
41   * <p>Typically an interceptor chain is defined per
42   * {@link HandlerMapping} bean, sharing its
43   * granularity. To be able to apply a certain interceptor chain to a group of
44   * handlers, one needs to map the desired handlers via one
45   * {@code HandlerMapping} bean. The interceptors themselves are defined as
46   * beans in the application context, referenced by the mapping bean definition
47   * via its
48   * {@link org.springframework.web.portlet.handler.AbstractHandlerMapping#setInterceptors "interceptors"}
49   * property (in XML: a &lt;list&gt; of &lt;ref&gt; elements).
50   *
51   * <p>A {@code HandlerInterceptor} is basically similar to a Servlet
52   * {@link javax.servlet.Filter}, but in contrast to the latter it allows
53   * custom pre-processing with the option to prohibit the execution of the handler
54   * itself, and custom post-processing. {@code Filters} are more powerful;
55   * for example they allow for exchanging the request and response objects that
56   * are handed down the chain. Note that a filter gets configured in
57   * {@code web.xml}, a {@code HandlerInterceptor} in the application context.
58   *
59   * <p>As a basic guideline, fine-grained handler-related pre-processing tasks are
60   * candidates for {@code HandlerInterceptor} implementations, especially
61   * factored-out common handler code and authorization checks. On the other hand,
62   * a {@code Filter} is well-suited for request content and view content
63   * handling, like multipart forms and GZIP compression. This typically shows when
64   * one needs to map the filter to certain content types (e.g. images), or to all
65   * requests.
66   *
67   * <p>Be aware that filters cannot be applied to portlet requests (they
68   * only operate on servlet requests), so for portlet requests interceptors are
69   * essential.
70   *
71   * <p>If we assume a "sunny day" request cycle (i.e. a request where nothing goes wrong
72   * and all is well), the workflow of a {@code HandlerInterceptor} will be as
73   * follows:
74   *
75   * <p><b>Action Request:</b><p>
76   * <ol>
77   * <li>{@code DispatcherPortlet} maps the action request to a particular handler and
78   * assembles a handler execution chain consisting of the handler that is to be invoked
79   * and all of the {@code HandlerInterceptor} instances that apply to the request.</li>
80   * <li>{@link HandlerInterceptor#preHandleAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse, Object) preHandleAction(..)}
81   * is called; if the invocation of this method returns {@code true} then this workflow continues.</li>
82   * <li>The target handler handles the action request (via
83   * {@link HandlerAdapter#handleAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse, Object) HandlerAdapter.handleAction(..)}).</li>
84   * <li>{@link HandlerInterceptor#afterActionCompletion(javax.portlet.ActionRequest, javax.portlet.ActionResponse, Object, Exception) afterActionCompletion(..)}
85   * is called.</li>
86   * </ol>
87   *
88   * <p><b>Render Request:</b><p>
89   * <ol>
90   * <li>{@code DispatcherPortlet} maps the render request to a particular handler and
91   * assembles a handler execution chain consisting of the handler that is to be invoked
92   * and all of the {@code HandlerInterceptor} instances that apply to the request.</li>
93   * <li>{@link HandlerInterceptor#preHandleRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object) preHandleRender(..)}
94   * is called; if the invocation of this method returns {@code true} then this workflow continues.</li>
95   * <li>The target handler handles the render request (via
96   * {@link HandlerAdapter#handleRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object) HandlerAdapter.handleRender(..)}).</li>
97   * <li>{@link HandlerInterceptor#postHandleRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object, ModelAndView) postHandleRender(..)}
98   * is called.</li>
99   * <li>If the {@code HandlerAdapter} returned a {@code ModelAndView}, then
100  * {@code DispatcherPortlet} renders the view accordingly.
101  * <li>{@link HandlerInterceptor#afterRenderCompletion(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object, Exception) afterRenderCompletion(..)}
102  * is called.</li>
103  * </ol>
104  *
105  * @author Juergen Hoeller
106  * @author John A. Lewis
107  * @since 2.0
108  * @see HandlerExecutionChain#getInterceptors
109  * @see HandlerMapping
110  * @see org.springframework.web.portlet.handler.AbstractHandlerMapping#setInterceptors
111  * @see HandlerExecutionChain
112  */
113 public interface HandlerInterceptor {
114 
115 	/**
116 	 * Intercept the execution of a handler in the action phase.
117 	 * <p>Called after a HandlerMapping determines an appropriate handler object
118 	 * to handle an {@link ActionRequest}, but before said HandlerAdapter actually
119 	 * invokes the handler.
120 	 * <p>{@link DispatcherPortlet} processes a handler in an execution chain,
121 	 * consisting of any number of interceptors, with the handler itself at the end.
122 	 * With this method, each interceptor can decide to abort the execution chain,
123 	 * typically throwing an exception or writing a custom response.
124 	 * @param request current portlet action request
125 	 * @param response current portlet action response
126 	 * @param handler chosen handler to execute, for type and/or instance evaluation
127 	 * @return {@code true} if the execution chain should proceed with the
128 	 * next interceptor or the handler itself. Else, {@code DispatcherPortlet}
129 	 * assumes that this interceptor has already dealt with the response itself
130 	 * @throws Exception in case of errors
131 	 */
132 	boolean preHandleAction(ActionRequest request, ActionResponse response, Object handler)
133 			throws Exception;
134 
135 	/**
136 	 * Callback after completion of request processing in the action phase, that is,
137 	 * after rendering the view. Will be called on any outcome of handler execution,
138 	 * thus allowing for proper resource cleanup.
139 	 * <p>Note: Will only be called if this interceptor's
140 	 * {@link #preHandleAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse, Object)}
141 	 * method has successfully completed and returned {@code true}!
142 	 * @param request current portlet action request
143 	 * @param response current portlet action response
144 	 * @param handler chosen handler to execute, for type and/or instance examination
145 	 * @param ex exception thrown on handler execution, if any (only included as
146 	 * additional context information for the case where a handler threw an exception;
147 	 * request execution may have failed even when this argument is {@code null})
148 	 * @throws Exception in case of errors
149 	 */
150 	void afterActionCompletion(ActionRequest request, ActionResponse response, Object handler, Exception ex)
151 			throws Exception;
152 
153 	/**
154 	 * Intercept the execution of a handler in the render phase.
155 	 * <p>Called after a HandlerMapping determines an appropriate handler object
156 	 * to handle a {@link RenderRequest}, but before said HandlerAdapter actually
157 	 * invokes the handler.
158 	 * <p>{@link DispatcherPortlet} processes a handler in an execution chain,
159 	 * consisting of any number of interceptors, with the handler itself at the end.
160 	 * With this method, each interceptor can decide to abort the execution chain,
161 	 * typically throwing an exception or writing a custom response.
162 	 * @param request current portlet render request
163 	 * @param response current portlet render response
164 	 * @param handler chosen handler to execute, for type and/or instance evaluation
165 	 * @return {@code true} if the execution chain should proceed with the
166 	 * next interceptor or the handler itself. Else, {@code DispatcherPortlet}
167 	 * assumes that this interceptor has already dealt with the response itself
168 	 * @throws Exception in case of errors
169 	 */
170 	boolean preHandleRender(RenderRequest request, RenderResponse response, Object handler)
171 			throws Exception;
172 
173 	/**
174 	 * Intercept the execution of a handler in the render phase.
175 	 * <p>Called after a {@link HandlerAdapter} actually invoked the handler, but
176 	 * before the {@code DispatcherPortlet} renders the view. Can thus expose
177 	 * additional model objects to the view via the given {@link ModelAndView}.
178 	 * <p>{@code DispatcherPortlet} processes a handler in an execution chain,
179 	 * consisting of any number of interceptors, with the handler itself at the end.
180 	 * With this method, each interceptor can post-process an execution, getting
181 	 * applied in inverse order of the execution chain.
182 	 * @param request current portlet render request
183 	 * @param response current portlet render response
184 	 * @param handler chosen handler to execute, for type and/or instance examination
185 	 * @param modelAndView the {@code ModelAndView} that the handler returned
186 	 * (can also be {@code null})
187 	 * @throws Exception in case of errors
188 	 */
189 	void postHandleRender(RenderRequest request, RenderResponse response, Object handler, ModelAndView modelAndView)
190 			throws Exception;
191 
192 	/**
193 	 * Callback after completion of request processing, that is, after rendering
194 	 * the view. Will be called on any outcome of handler execution, thus allowing
195 	 * for proper resource cleanup.
196 	 * <p>Note: Will only be called if this interceptor's
197 	 * {@link #preHandleRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object)}
198 	 * method has successfully completed and returned {@code true}!
199 	 * @param request current portlet render request
200 	 * @param response current portlet render response
201 	 * @param handler chosen handler to execute, for type and/or instance examination
202 	 * @param ex exception thrown on handler execution, if any
203 	 * @throws Exception in case of errors
204 	 */
205 	void afterRenderCompletion(RenderRequest request, RenderResponse response, Object handler, Exception ex)
206 			throws Exception;
207 
208 	/**
209 	 * Intercept the execution of a handler in the render phase.
210 	 * <p>Called after a HandlerMapping determines an appropriate handler object
211 	 * to handle a {@link RenderRequest}, but before said HandlerAdapter actually
212 	 * invokes the handler.
213 	 * <p>{@link DispatcherPortlet} processes a handler in an execution chain,
214 	 * consisting of any number of interceptors, with the handler itself at the end.
215 	 * With this method, each interceptor can decide to abort the execution chain,
216 	 * typically throwing an exception or writing a custom response.
217 	 * @param request current portlet render request
218 	 * @param response current portlet render response
219 	 * @param handler chosen handler to execute, for type and/or instance evaluation
220 	 * @return {@code true} if the execution chain should proceed with the
221 	 * next interceptor or the handler itself. Else, {@code DispatcherPortlet}
222 	 * assumes that this interceptor has already dealt with the response itself
223 	 * @throws Exception in case of errors
224 	 */
225 	boolean preHandleResource(ResourceRequest request, ResourceResponse response, Object handler)
226 			throws Exception;
227 
228 	/**
229 	 * Intercept the execution of a handler in the render phase.
230 	 * <p>Called after a {@link HandlerAdapter} actually invoked the handler, but
231 	 * before the {@code DispatcherPortlet} renders the view. Can thus expose
232 	 * additional model objects to the view via the given {@link ModelAndView}.
233 	 * <p>{@code DispatcherPortlet} processes a handler in an execution chain,
234 	 * consisting of any number of interceptors, with the handler itself at the end.
235 	 * With this method, each interceptor can post-process an execution, getting
236 	 * applied in inverse order of the execution chain.
237 	 * @param request current portlet render request
238 	 * @param response current portlet render response
239 	 * @param handler chosen handler to execute, for type and/or instance examination
240 	 * @param modelAndView the {@code ModelAndView} that the handler returned
241 	 * (can also be {@code null})
242 	 * @throws Exception in case of errors
243 	 */
244 	void postHandleResource(ResourceRequest request, ResourceResponse response, Object handler, ModelAndView modelAndView)
245 			throws Exception;
246 
247 	/**
248 	 * Callback after completion of request processing, that is, after rendering
249 	 * the view. Will be called on any outcome of handler execution, thus allowing
250 	 * for proper resource cleanup.
251 	 * <p>Note: Will only be called if this interceptor's
252 	 * {@link #preHandleRender(javax.portlet.RenderRequest, javax.portlet.RenderResponse, Object)}
253 	 * method has successfully completed and returned {@code true}!
254 	 * @param request current portlet render request
255 	 * @param response current portlet render response
256 	 * @param handler chosen handler to execute, for type and/or instance examination
257 	 * @param ex exception thrown on handler execution, if any
258 	 * @throws Exception in case of errors
259 	 */
260 	void afterResourceCompletion(ResourceRequest request, ResourceResponse response, Object handler, Exception ex)
261 			throws Exception;
262 
263 	/**
264 	 * Intercept the execution of a handler in the action phase.
265 	 * <p>Called after a HandlerMapping determines an appropriate handler object
266 	 * to handle an {@link ActionRequest}, but before said HandlerAdapter actually
267 	 * invokes the handler.
268 	 * <p>{@link DispatcherPortlet} processes a handler in an execution chain,
269 	 * consisting of any number of interceptors, with the handler itself at the end.
270 	 * With this method, each interceptor can decide to abort the execution chain,
271 	 * typically throwing an exception or writing a custom response.
272 	 * @param request current portlet action request
273 	 * @param response current portlet action response
274 	 * @param handler chosen handler to execute, for type and/or instance evaluation
275 	 * @return {@code true} if the execution chain should proceed with the
276 	 * next interceptor or the handler itself. Else, {@code DispatcherPortlet}
277 	 * assumes that this interceptor has already dealt with the response itself
278 	 * @throws Exception in case of errors
279 	 */
280 	boolean preHandleEvent(EventRequest request, EventResponse response, Object handler)
281 			throws Exception;
282 
283 	/**
284 	 * Callback after completion of request processing in the action phase, that is,
285 	 * after rendering the view. Will be called on any outcome of handler execution,
286 	 * thus allowing for proper resource cleanup.
287 	 * <p>Note: Will only be called if this interceptor's
288 	 * {@link #preHandleAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse, Object)}
289 	 * method has successfully completed and returned {@code true}!
290 	 * @param request current portlet action request
291 	 * @param response current portlet action response
292 	 * @param handler chosen handler to execute, for type and/or instance examination
293 	 * @param ex exception thrown on handler execution, if any (only included as
294 	 * additional context information for the case where a handler threw an exception;
295 	 * request execution may have failed even when this argument is {@code null})
296 	 * @throws Exception in case of errors
297 	 */
298 	void afterEventCompletion(EventRequest request, EventResponse response, Object handler, Exception ex)
299 			throws Exception;
300 
301 }