1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.dispatcher;
23
24 import java.io.IOException;
25
26 import javax.servlet.Filter;
27 import javax.servlet.FilterChain;
28 import javax.servlet.FilterConfig;
29 import javax.servlet.ServletException;
30 import javax.servlet.ServletRequest;
31 import javax.servlet.ServletResponse;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34
35 import com.opensymphony.xwork2.ActionContext;
36 import com.opensymphony.xwork2.util.logging.Logger;
37 import com.opensymphony.xwork2.util.logging.LoggerFactory;
38 import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
39
40 /***
41 * <!-- SNIPPET START: description -->
42 * Special filter designed to work with the {@link FilterDispatcher} and allow
43 * for easier integration with SiteMesh. Normally, ordering your filters to have
44 * SiteMesh go first, and then {@link FilterDispatcher} go second is perfectly fine.
45 * However, sometimes you may wish to access Struts features, including the
46 * value stack, from within your SiteMesh decorators. Because {@link FilterDispatcher}
47 * cleans up the {@link ActionContext}, your decorator won't have access to the
48 * data you want.
49 * <p/>
50 * <p/>
51 * By adding this filter, the {@link FilterDispatcher} will know to not clean up and
52 * instead defer cleanup to this filter. The ordering of the filters should then be:
53 * <p/>
54 * <ul>
55 * <li>this filter</li>
56 * <li>SiteMesh filter</li>
57 * <li>{@link FilterDispatcher}</li>
58 * </ul>
59 * <!-- SNIPPET END: description -->
60 *
61 *
62 * @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and
63 * {@link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter} to use other Servlet filters that need access to
64 * the ActionContext
65 * @see FilterDispatcher
66 * @see Dispatcher
67 * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
68 * @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter
69 *
70 * @version $Date: 2008-07-07 10:10:42 -0400 (Mon, 07 Jul 2008) $ $Id: ActionContextCleanUp.java 674498 2008-07-07 14:10:42Z mrdon $
71 */
72 public class ActionContextCleanUp implements Filter {
73
74 private static final Logger LOG = LoggerFactory.getLogger(ActionContextCleanUp.class);
75
76 private static final String COUNTER = "__cleanup_recursion_counter";
77
78 /***
79 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
80 */
81 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
82
83 HttpServletRequest request = (HttpServletRequest) req;
84 HttpServletResponse response = (HttpServletResponse) res;
85
86 String timerKey = "ActionContextCleanUp_doFilter: ";
87 try {
88 UtilTimerStack.push(timerKey);
89
90 try {
91 Integer count = (Integer)request.getAttribute(COUNTER);
92 if (count == null) {
93 count = Integer.valueOf(1);
94 }
95 else {
96 count = Integer.valueOf(count.intValue()+1);
97 }
98 request.setAttribute(COUNTER, count);
99
100
101
102 chain.doFilter(request, response);
103 } finally {
104 int counterVal = ((Integer)request.getAttribute(COUNTER)).intValue();
105 counterVal -= 1;
106 request.setAttribute(COUNTER, Integer.valueOf(counterVal));
107 cleanUp(request);
108 }
109 }
110 finally {
111 UtilTimerStack.pop(timerKey);
112 }
113 }
114
115 /***
116 * Clean up the request of threadlocals if this is the last execution
117 *
118 * @param req The servlet request
119 */
120 protected static void cleanUp(ServletRequest req) {
121
122 Integer count = (Integer) req.getAttribute(COUNTER);
123 if (count != null && count > 0 ) {
124 if (LOG.isDebugEnabled()) {
125 LOG.debug("skipping cleanup counter="+count);
126 }
127 return;
128 }
129
130
131 ActionContext.setContext(null);
132 Dispatcher.setInstance(null);
133 }
134
135 public void destroy() {
136 }
137
138 public void init(FilterConfig arg0) throws ServletException {
139 }
140 }