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}