来源:http://ully.iteye.com/blog/1334925
在spring中,filter都默认继承OncePerRequestFilter,但为什么要这样呢?
OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行。
- public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
- throw new ServletException("OncePerRequestFilter just supports HTTP requests");
- }
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
- if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {
- // Proceed without invoking this filter...
- filterChain.doFilter(request, response);
- }
- else {
- // Do invoke this filter...
- request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
- try {
- doFilterInternal(httpRequest, httpResponse, filterChain);
- }
- finally {
- // Remove the "already filtered" request attribute for this request.
- request.removeAttribute(alreadyFilteredAttributeName);
- }
- }
- }
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { throw new ServletException("OncePerRequestFilter just supports HTTP requests"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName(); if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) { // Proceed without invoking this filter... filterChain.doFilter(request, response); } else { // Do invoke this filter... request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); try { doFilterInternal(httpRequest, httpResponse, filterChain); } finally { // Remove the "already filtered" request attribute for this request. request.removeAttribute(alreadyFilteredAttributeName); } } }
大家常识上都认为,一次请求本来就只过一次,为什么还要由此特别限定呢,呵呵实际上我们常识和实际的实现并不真的一样,经过一番查阅后,此方式是为了兼容不同的web container,特意而为之(jsr168),也就是说并不是所有的container都像我们期望的只过滤一次,servlet版本不同,表现也不同:。
写道
/**
* Filter base class that guarantees to be just executed once per request,
* on any servlet container. It provides a {@link #doFilterInternal}
* method with HttpServletRequest and HttpServletResponse arguments.
*
* <p>The {@link #getAlreadyFilteredAttributeName} method determines how
* to identify that a request is already filtered. The default implementation
* is based on the configured name of the concrete filter instance.
*
* @author Juergen Hoeller
* @since 06.12.2003
*/
* Filter base class that guarantees to be just executed once per request,
* on any servlet container. It provides a {@link #doFilterInternal}
* method with HttpServletRequest and HttpServletResponse arguments.
*
* <p>The {@link #getAlreadyFilteredAttributeName} method determines how
* to identify that a request is already filtered. The default implementation
* is based on the configured name of the concrete filter instance.
*
* @author Juergen Hoeller
* @since 06.12.2003
*/
如,servlet2.3与servlet2.4也有一定差异
写道
在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ include file="/index.jsp"%>的情况。
到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要 forward的时候也用到Filter。
到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要 forward的时候也用到Filter。
因此,为了兼容各种不同的运行环境和版本,默认filter继承OncePerRequestFilter是一个比较稳妥的选择。
相关推荐
一个简单的OncePerRequestFilter实现,可以为HTTP响应添加CORS相关标头。 入门 包括JAR 包括JAR文件作为对项目的依赖项。 它可以通过Maven Central获得。 玛文 <groupId>io.sprucehill <artifactId>spring-...
在Spring体系中,过滤器的定义我们一般采用继承OncePerRequestFilter的方式,当然也可以使用原始的Filter。 错误写法一: 如果不对request和response进行处理,使用伪代码采用如下写法打印请求和响应参数(注:此时...
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ...
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ...
问题背景 我们在使用SpringSecurity作为后台权限...制定了正确的忽略URL,内置的过滤器不走,但是我们自己定义的,实现了OncePerRequestFilter的过滤器还是会走的。 配置方法 通过先这段代码便完成了我们登录路径的配置
Spring提供的CharacterEncoding和OpenSessionInView功能
servlet的过滤器,完成必须登录,才能访问资源,简单易懂
org.springframework.web.filter.OncePerRequestFilter.class org.springframework.web.filter.RequestContextFilter.class org.springframework.web.filter.ServletContextRequestLoggingFilter.class org.spring...
OncePerRequestFilter OpenEntityManagerInViewFilter OpenEntityManagerInViewInterceptor OpenPersistenceManagerInViewFilter OpenPersistenceManagerInViewInterceptor OpenSessionInViewFilter ...
其中additionalAuthenticationChecks用于校验用户密码等信息)、AuthenticationSuccessHandler(认证成功处理器)、AuthenticationFailureHandler(认证失败处理器)、OncePerRequestFilter(过滤器,用于增加额外...
appfuse的webapp包下有这么几个包一:org.appfuse.webapp.filter这个包下定义了一些过滤器首先是GZIPFilter继承实现了spring提供的抽象类OncePerRequestFilter(每一次请求执行一次的过滤器)的doFilterInternal方法。...