/*
 * Copyright 2002-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

Servlet Filter that exposes the request to the current thread, through both LocaleContextHolder and RequestContextHolder. To be registered as filter in web.xml.

Alternatively, Spring's RequestContextListener and Spring's DispatcherServlet also expose the same request context to the current thread.

This filter is mainly for use with third-party servlets, e.g. the JSF FacesServlet. Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient.

Author:Juergen Hoeller, Rod Johnson, Rossen Stoyanchev
See Also:
Since:2.0
/** * Servlet Filter that exposes the request to the current thread, * through both {@link org.springframework.context.i18n.LocaleContextHolder} and * {@link RequestContextHolder}. To be registered as filter in {@code web.xml}. * * <p>Alternatively, Spring's {@link org.springframework.web.context.request.RequestContextListener} * and Spring's {@link org.springframework.web.servlet.DispatcherServlet} also expose * the same request context to the current thread. * * <p>This filter is mainly for use with third-party servlets, e.g. the JSF FacesServlet. * Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient. * * @author Juergen Hoeller * @author Rod Johnson * @author Rossen Stoyanchev * @since 2.0 * @see org.springframework.context.i18n.LocaleContextHolder * @see org.springframework.web.context.request.RequestContextHolder * @see org.springframework.web.context.request.RequestContextListener * @see org.springframework.web.servlet.DispatcherServlet */
public class RequestContextFilter extends OncePerRequestFilter { private boolean threadContextInheritable = false;
Set whether to expose the LocaleContext and RequestAttributes as inheritable for child threads (using an InheritableThreadLocal).

Default is "false", to avoid side effects on spawned background threads. Switch this to "true" to enable inheritance for custom child threads which are spawned during request processing and only used for this request (that is, ending after their initial task, without reuse of the thread).

WARNING: Do not use inheritance for child threads if you are accessing a thread pool which is configured to potentially add new threads on demand (e.g. a JDK ThreadPoolExecutor), since this will expose the inherited context to such a pooled thread.

/** * Set whether to expose the LocaleContext and RequestAttributes as inheritable * for child threads (using an {@link java.lang.InheritableThreadLocal}). * <p>Default is "false", to avoid side effects on spawned background threads. * Switch this to "true" to enable inheritance for custom child threads which * are spawned during request processing and only used for this request * (that is, ending after their initial task, without reuse of the thread). * <p><b>WARNING:</b> Do not use inheritance for child threads if you are * accessing a thread pool which is configured to potentially add new threads * on demand (e.g. a JDK {@link java.util.concurrent.ThreadPoolExecutor}), * since this will expose the inherited context to such a pooled thread. */
public void setThreadContextInheritable(boolean threadContextInheritable) { this.threadContextInheritable = threadContextInheritable; }
Returns "false" so that the filter may set up the request context in each asynchronously dispatched thread.
/** * Returns "false" so that the filter may set up the request context in each * asynchronously dispatched thread. */
@Override protected boolean shouldNotFilterAsyncDispatch() { return false; }
Returns "false" so that the filter may set up the request context in an error dispatch.
/** * Returns "false" so that the filter may set up the request context in an * error dispatch. */
@Override protected boolean shouldNotFilterErrorDispatch() { return false; } @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ServletRequestAttributes attributes = new ServletRequestAttributes(request, response); initContextHolders(request, attributes); try { filterChain.doFilter(request, response); } finally { resetContextHolders(); if (logger.isTraceEnabled()) { logger.trace("Cleared thread-bound request context: " + request); } attributes.requestCompleted(); } } private void initContextHolders(HttpServletRequest request, ServletRequestAttributes requestAttributes) { LocaleContextHolder.setLocale(request.getLocale(), this.threadContextInheritable); RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable); if (logger.isTraceEnabled()) { logger.trace("Bound request context to thread: " + request); } } private void resetContextHolders() { LocaleContextHolder.resetLocaleContext(); RequestContextHolder.resetRequestAttributes(); } }