1 /*
2 * Copyright 2002-2008 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.context.request;
18
19 import javax.servlet.ServletRequestEvent;
20 import javax.servlet.ServletRequestListener;
21 import javax.servlet.http.HttpServletRequest;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import org.springframework.context.i18n.LocaleContextHolder;
27
28 /**
29 * Servlet 2.4+ listener that exposes the request to the current thread,
30 * through both {@link org.springframework.context.i18n.LocaleContextHolder} and
31 * {@link RequestContextHolder}. To be registered as listener in <code>web.xml</code>.
32 *
33 * <p>Alternatively, Spring's {@link org.springframework.web.filter.RequestContextFilter}
34 * and Spring's {@link org.springframework.web.servlet.DispatcherServlet} also expose
35 * the same request context to the current thread. In contrast to this listener,
36 * advanced options are available there (e.g. "threadContextInheritable").
37 *
38 * <p>This listener is mainly for use with third-party servlets, e.g. the JSF FacesServlet.
39 * Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient.
40 *
41 * @author Juergen Hoeller
42 * @since 2.0
43 * @see javax.servlet.ServletRequestListener
44 * @see org.springframework.context.i18n.LocaleContextHolder
45 * @see org.springframework.web.context.request.RequestContextHolder
46 * @see org.springframework.web.filter.RequestContextFilter
47 * @see org.springframework.web.servlet.DispatcherServlet
48 */
49 public class RequestContextListener implements ServletRequestListener {
50
51 private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
52 RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
53
54 /** Logger available to subclasses */
55 protected final Log logger = LogFactory.getLog(getClass());
56
57
58 public void requestInitialized(ServletRequestEvent requestEvent) {
59 if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
60 throw new IllegalArgumentException(
61 "Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
62 }
63 HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
64 ServletRequestAttributes attributes = new ServletRequestAttributes(request);
65 request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
66 LocaleContextHolder.setLocale(request.getLocale());
67 RequestContextHolder.setRequestAttributes(attributes);
68 if (logger.isDebugEnabled()) {
69 logger.debug("Bound request context to thread: " + request);
70 }
71 }
72
73 public void requestDestroyed(ServletRequestEvent requestEvent) {
74 ServletRequestAttributes attributes =
75 (ServletRequestAttributes) requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
76 ServletRequestAttributes threadAttributes =
77 (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
78 if (threadAttributes != null) {
79 // We're assumably within the original request thread...
80 if (attributes == null) {
81 attributes = threadAttributes;
82 }
83 RequestContextHolder.resetRequestAttributes();
84 LocaleContextHolder.resetLocaleContext();
85 }
86 if (attributes != null) {
87 attributes.requestCompleted();
88 if (logger.isDebugEnabled()) {
89 logger.debug("Cleared thread-bound request context: " + requestEvent.getServletRequest());
90 }
91 }
92 }
93
94 }