KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > filter > DelegatingFilterProxy


1 /*
2  * Copyright 2002-2006 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.filter;
18
19 import java.io.IOException JavaDoc;
20
21 import javax.servlet.Filter JavaDoc;
22 import javax.servlet.FilterChain JavaDoc;
23 import javax.servlet.ServletException JavaDoc;
24 import javax.servlet.ServletRequest JavaDoc;
25 import javax.servlet.ServletResponse JavaDoc;
26
27 import org.springframework.web.context.WebApplicationContext;
28 import org.springframework.web.context.support.WebApplicationContextUtils;
29
30 /**
31  * Proxy for a standard Servlet 2.3 Filter, delegating to a Spring-managed
32  * bean that implements the Filter interface. Supports a "targetBeanName"
33  * filter init-param in <code>web.xml</code>, specifying the name of the
34  * target bean in the Spring application context.
35  *
36  * <p><code>web.xml</code> will usually contain a DelegatingFilterProxy definition,
37  * with the specified <code>filter-name</code> corresponding to a bean name in
38  * Spring's root application context. All calls to the filter proxy will then
39  * be delegated to that bean in the Spring context, which is required to implement
40  * the standard Servlet 2.3 Filter interface.
41  *
42  * <p>This approach is particularly useful for Filter implementation with complex
43  * setup needs, allowing to apply the full Spring bean definition machinery to
44  * Filter instances. Alternatively, consider standard Filter setup in combination
45  * with looking up service beans from the Spring root application context.
46  *
47  * <p><b>NOTE:</b> The lifecycle methods defined by the Servlet Filter interface
48  * will by default <i>not</i> be delegated to the target bean, relying on the
49  * Spring application context to manage the lifecycle of that bean. Specifying
50  * the "targetFilterLifecycle" filter init-param as "true" will enforce invocation
51  * of the <code>Filter.init</code> and <code>Filter.destroy</code> lifecycle methods
52  * on the target bean, letting the servlet container manage the filter lifecycle.
53  *
54  * <p>This class is inspired by Acegi Security's FilterToBeanProxy class,
55  * written by Ben Alex.
56  *
57  * @author Juergen Hoeller
58  * @since 1.2
59  * @see #setTargetBeanName
60  * @see #setTargetFilterLifecycle
61  * @see javax.servlet.Filter#doFilter
62  * @see javax.servlet.Filter#init
63  * @see javax.servlet.Filter#destroy
64  */

65 public class DelegatingFilterProxy extends GenericFilterBean {
66
67     private String JavaDoc targetBeanName;
68
69     private boolean targetFilterLifecycle = false;
70
71     private Filter JavaDoc delegate;
72
73
74     /**
75      * Set the name of the target bean in the Spring application context.
76      * The target bean must implement the standard Servlet 2.3 Filter interface.
77      * <p>By default, the <code>filter-name</code> as specified for the
78      * DelegatingFilterProxy in <code>web.xml</code> will be used.
79      */

80     public void setTargetBeanName(String JavaDoc targetBeanName) {
81         this.targetBeanName = targetBeanName;
82     }
83
84     /**
85      * Return the name of the target bean in the Spring application context.
86      */

87     protected String JavaDoc getTargetBeanName() {
88         return targetBeanName;
89     }
90
91     /**
92      * Set whether to invoke the <code>Filter.init</code> and
93      * <code>Filter.destroy</code> lifecycle methods on the target bean.
94      * <p>Default is "false"; target beans usually rely on the Spring application
95      * context for managing their lifecycle. Setting this flag to "true" means
96      * that the servlet container will control the lifecycle of the target
97      * Filter, with this proxy delegating the corresponding calls.
98      */

99     public void setTargetFilterLifecycle(boolean targetFilterLifecycle) {
100         this.targetFilterLifecycle = targetFilterLifecycle;
101     }
102
103     /**
104      * Return whether to invoke the <code>Filter.init</code> and
105      * <code>Filter.destroy</code> lifecycle methods on the target bean.
106      */

107     protected boolean isTargetFilterLifecycle() {
108         return targetFilterLifecycle;
109     }
110
111
112     protected void initFilterBean() throws ServletException JavaDoc {
113         // If no target bean name specified, use filter name.
114
if (this.targetBeanName == null) {
115             this.targetBeanName = getFilterName();
116         }
117         // Fetch Spring root application context and initialize the delegate early,
118
// if possible. If the root application context will be started after this
119
// filter proxy, we'll have to resort to lazy initialization.
120
WebApplicationContext wac =
121                 WebApplicationContextUtils.getWebApplicationContext(getServletContext());
122         if (wac != null) {
123             this.delegate = initDelegate(wac);
124         }
125     }
126
127     public void doFilter(ServletRequest JavaDoc request, ServletResponse JavaDoc response, FilterChain JavaDoc filterChain)
128             throws ServletException JavaDoc, IOException JavaDoc {
129
130         // Lazily initialize the delegate if necessary.
131
if (this.delegate == null) {
132             WebApplicationContext wac =
133                     WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
134             this.delegate = initDelegate(wac);
135         }
136
137         // Let the delegate perform the actual doFilter opeation.
138
this.delegate.doFilter(request, response, filterChain);
139     }
140
141     public void destroy() {
142         if (this.delegate != null) {
143             destroyDelegate(this.delegate);
144         }
145     }
146
147
148     /**
149      * Initialize the Filter delegate, defined as bean the given Spring
150      * application context.
151      * <p>Default implementation fetches the bean from the application context
152      * and calls the standard <code>Filter.init</code> method on it, passing
153      * in the FilterConfig of this Filter proxy.
154      * @param wac the root application context
155      * @return the initialized delegate Filter
156      * @throws ServletException if thrown by the Filter
157      * @see #getTargetBeanName()
158      * @see #isTargetFilterLifecycle()
159      * @see #getFilterConfig()
160      * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
161      */

162     protected Filter JavaDoc initDelegate(WebApplicationContext wac) throws ServletException JavaDoc {
163         Filter JavaDoc delegate = (Filter JavaDoc) wac.getBean(getTargetBeanName(), Filter JavaDoc.class);
164         if (isTargetFilterLifecycle()) {
165             delegate.init(getFilterConfig());
166         }
167         return delegate;
168     }
169
170     /**
171      * Destroy the Filter delegate.
172      * Default implementation simply calls <code>Filter.destroy</code> on it.
173      * @param delegate the Filter delegate (never <code>null</code>)
174      * @see #isTargetFilterLifecycle()
175      * @see javax.servlet.Filter#destroy()
176      */

177     protected void destroyDelegate(Filter JavaDoc delegate) {
178         if (isTargetFilterLifecycle()) {
179             this.delegate.destroy();
180         }
181     }
182
183 }
184
Popular Tags