001/*
002 * Copyright 2002-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.context.request;
018
019import javax.servlet.ServletRequestEvent;
020import javax.servlet.ServletRequestListener;
021import javax.servlet.http.HttpServletRequest;
022
023import org.springframework.context.i18n.LocaleContextHolder;
024
025/**
026 * Servlet listener that exposes the request to the current thread,
027 * through both {@link org.springframework.context.i18n.LocaleContextHolder} and
028 * {@link RequestContextHolder}. To be registered as listener in {@code web.xml}.
029 *
030 * <p>Alternatively, Spring's {@link org.springframework.web.filter.RequestContextFilter}
031 * and Spring's {@link org.springframework.web.servlet.DispatcherServlet} also expose
032 * the same request context to the current thread. In contrast to this listener,
033 * advanced options are available there (e.g. "threadContextInheritable").
034 *
035 * <p>This listener is mainly for use with third-party servlets, e.g. the JSF FacesServlet.
036 * Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient.
037 *
038 * @author Juergen Hoeller
039 * @since 2.0
040 * @see javax.servlet.ServletRequestListener
041 * @see org.springframework.context.i18n.LocaleContextHolder
042 * @see RequestContextHolder
043 * @see org.springframework.web.filter.RequestContextFilter
044 * @see org.springframework.web.servlet.DispatcherServlet
045 */
046public class RequestContextListener implements ServletRequestListener {
047
048        private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
049                        RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
050
051
052        @Override
053        public void requestInitialized(ServletRequestEvent requestEvent) {
054                if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
055                        throw new IllegalArgumentException(
056                                        "Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
057                }
058                HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
059                ServletRequestAttributes attributes = new ServletRequestAttributes(request);
060                request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
061                LocaleContextHolder.setLocale(request.getLocale());
062                RequestContextHolder.setRequestAttributes(attributes);
063        }
064
065        @Override
066        public void requestDestroyed(ServletRequestEvent requestEvent) {
067                ServletRequestAttributes attributes = null;
068                Object reqAttr = requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
069                if (reqAttr instanceof ServletRequestAttributes) {
070                        attributes = (ServletRequestAttributes) reqAttr;
071                }
072                RequestAttributes threadAttributes = RequestContextHolder.getRequestAttributes();
073                if (threadAttributes != null) {
074                        // We're assumably within the original request thread...
075                        LocaleContextHolder.resetLocaleContext();
076                        RequestContextHolder.resetRequestAttributes();
077                        if (attributes == null && threadAttributes instanceof ServletRequestAttributes) {
078                                attributes = (ServletRequestAttributes) threadAttributes;
079                        }
080                }
081                if (attributes != null) {
082                        attributes.requestCompleted();
083                }
084        }
085
086}