`

OncePerRequestFilter

 
阅读更多

来源:http://ully.iteye.com/blog/1334925

在spring中,filter都默认继承OncePerRequestFilter,但为什么要这样呢?

 

OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行。

 

Java代码 复制代码 收藏代码
  1. public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)   
  2.             throws ServletException, IOException {   
  3.   
  4.         if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {   
  5.             throw new ServletException("OncePerRequestFilter just supports HTTP requests");   
  6.         }   
  7.         HttpServletRequest httpRequest = (HttpServletRequest) request;   
  8.         HttpServletResponse httpResponse = (HttpServletResponse) response;   
  9.   
  10.         String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();   
  11.         if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {   
  12.             // Proceed without invoking this filter...   
  13.             filterChain.doFilter(request, response);   
  14.         }   
  15.         else {   
  16.             // Do invoke this filter...   
  17.             request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);   
  18.             try {   
  19.                 doFilterInternal(httpRequest, httpResponse, filterChain);   
  20.             }   
  21.             finally {   
  22.                 // Remove the "already filtered" request attribute for this request.   
  23.                 request.removeAttribute(alreadyFilteredAttributeName);   
  24.             }   
  25.         }   
  26.     }  
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
*/

 

如,servlet2.3与servlet2.4也有一定差异

 写道
在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ include file="/index.jsp"%>的情况。

到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要 forward的时候也用到Filter。

 因此,为了兼容各种不同的运行环境和版本,默认filter继承OncePerRequestFilter是一个比较稳妥的选择。

 

 

分享到:
评论

相关推荐

    spring-cors-filter:一个Spring Framework OncePerRequestFilter实现,用于将CORS标头应用于HTTP响应

    一个简单的OncePerRequestFilter实现,可以为HTTP响应添加CORS相关标头。 入门 包括JAR 包括JAR文件作为对项目的依赖项。 它可以通过Maven Central获得。 玛文  &lt;groupId&gt;io.sprucehill  &lt;artifactId&gt;spring-...

    在Spring MVC或Spring Boot中使用Filter打印请求参数问题

    Spring提供了`OncePerRequestFilter`抽象类,它是对传统`Filter`的一个封装,确保每个请求只被过滤一次,避免了在多线程环境下的并发问题。然而,如果在处理JSON类型的POST请求时,直接在Filter中打印请求参数,可能...

    SpringSecurity Jwt Token 自动刷新的实现

    public class TokenAuthenticateFilter extends OncePerRequestFilter { private final TokenProperties tokenProperties; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @Override ...

    java head space.txt

    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ...

    apache-tomcat-7.0.69.zip

    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ...

    java学习之SpringSecurity配置了登录链接无权限

    问题背景 我们在使用SpringSecurity作为后台权限...制定了正确的忽略URL,内置的过滤器不走,但是我们自己定义的,实现了OncePerRequestFilter的过滤器还是会走的。 配置方法 通过先这段代码便完成了我们登录路径的配置

    Halo 开源项目学习(三):注册与登录.doc

    AbstractAuthenticationFilter 又继承自 OncePerRequestFilter。 过滤器的执行逻辑 在过滤器的执行逻辑中,首先需要判断文章是否已安装。如果文章未安装且当前并不是测试环境,那么由 failureHandler 处理 ...

    Shiro开启CSRF表单防护

    2. 新建一个 CsrfFilter 类,继承自 OncePerRequestFilter,用于验证 Referer 字段。 3. 在 CsrfFilter 类中,检查 Referer 字段是否来自合法的域名,如果是,则放行请求;否则,阻止请求。 代码实现: ```java ...

    Spring提供的CharacterEncoding和OpenSessionInView功能

    Spring框架是Java开发中不可或缺的一部分,它为开发者提供了丰富的功能,包括依赖注入、面向切面编程、事务管理等。在处理Web应用时,Spring提供了一些关键特性,如`CharacterEncodingFilter`和`...

    CharacterEncodingFilter类的学习 .doc

    具体实现上,`CharacterEncodingFilter` 继承自 `OncePerRequestFilter`,后者提供了一个 `doFilterInternal` 方法,该方法在每个请求只执行一次,避免了多次过滤同一个请求。 `OncePerRequestFilter` 的 `doFilter...

    jquery字符编码转换[文].pdf

    public class MutilCharacterEncodingFilter extends OncePerRequestFilter { // ... 正则表达式匹配编码信息 ... // 在doFilterInternal方法中,检查请求参数并根据找到的编码信息设置响应编码 @Override ...

    SpringBoot +esapi 实现防止xss攻击 实战代码

    然后,我们需要创建一个自定义的过滤器,继承自`OncePerRequestFilter`,并覆盖`doFilterInternal`方法。在这个方法中,我们可以调用ESAPI的编码方法对请求参数进行处理: ```java import org.owasp.esapi.ESAPI; ...

    Springboot统一web请求日志

    要实现统一的Web请求日志,需要编写一个自定义过滤器,继承自`OncePerRequestFilter`。在`doFilterInternal`方法中,可以获取到HttpServletRequest和HttpServletResponse对象,从中提取出请求的方法、URL、参数、...

    过滤器例子下载实例

    在Java Web开发中,Servlet Filter是一个非常重要的概念,它允许我们在请求被Servlet处理之前或之后进行拦截和处理。本示例“过滤器例子下载实例”旨在演示如何使用Servlet Filter实现资源访问控制,确保只有经过...

    SpringSecurity集成JWT

    public class JwtRequestFilter extends OncePerRequestFilter { private final JwtAuthenticationProvider authenticationProvider; private final String secretKey; @Override protected void ...

    springboot整合jwt整合knife4j.zip

    创建一个`JwtFilter`类,继承自`OncePerRequestFilter`,并在`doFilterInternal`方法中解析和验证JWT。 ```java public class JwtFilter extends OncePerRequestFilter { // 实现解析和验证JWT的逻辑 } ``` 同时...

    swagger+springboot配置

    import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet...

    api鉴权-token验证机制springboot版本java后端

    public class JwtTokenFilter extends OncePerRequestFilter { // 验证Token的方法 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ...

    java单点登录流程及其他

    public class JwtAuthorizationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws...

    SpringBoot2.6整合SpringSecurity+JWT

    过滤器需要实现`OncePerRequestFilter`接口,并在`doFilterInternal`方法中实现JWT的解析和校验。 4. **配置AuthenticationProvider**:实现`AuthenticationProvider`接口,用于处理用户认证。在这个过程中,你可以...

Global site tag (gtag.js) - Google Analytics