`

OncePerRequestFilter的作用

 
阅读更多

在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);
			}
		}
	}

 

大家常识上都认为,一次请求本来就只过一次,为什么还要由此特别限定呢,呵呵实际上我们常识和实际的实现并不真的一样,经过一番查阅后,此方式是为了兼容不同的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提供的CharacterEncoding和OpenSessionInView功能

    `CharacterEncodingFilter`的作用就是确保请求和响应的字符编码统一为指定的格式,通常设置为UTF-8,避免因为编码问题导致的数据丢失或显示错误。通过在Web应用的配置文件(如web.xml)中添加该过滤器,可以全局设定...

    CharacterEncodingFilter类的学习 .doc

    `CharacterEncodingFilter` 的作用就是确保请求和响应都使用一致的字符编码,从而避免乱码现象。 配置 `CharacterEncodingFilter` 需要在 `web.xml` 文件中添加相应的过滤器配置,如下所示: ```xml ...

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

    failureHandler 的作用是处理异常请求,以确保系统的稳定性和安全性。 Halo 项目启动 在 Halo 项目启动时,需要安装文章并注册用户信息。当文章安装完成后,用户就可以根据注册的信息登录到管理员界面。在项目启动...

    Spring MVC过滤器-登录过滤的代码实现

    登录过滤器的主要作用是在用户访问特定资源(如后台管理界面)之前检查其是否已经登录。如果用户未登录,系统通常会重定向到登录页面或者显示错误消息。在Spring MVC中,我们可以自定义Filter来实现这一功能。下面是...

    appfuse源码分析三(web)

    appfuse的webapp包下有这么几个包一:org.appfuse.webapp.filter这个包下定义了一些过滤器首先是GZIPFilter继承实现了spring提供的抽象类OncePerRequestFilter(每一次请求执行一次的过滤器)的doFilterInternal方法。...

    SpringSecurity的防Csrf攻击实现代码解析

    Spring Security 中的 Csrf 攻击防御机制是通过 CsrfFilter 来实现的,该类继承自 OncePerRequestFilter,並在 doFilterInternal 方法中实现了 Csrf Token 的生成、验证和匹配。CsrfFilter 的主要作用是保护 Web ...

    Shiro 控制并发登录人数限制及登录踢出的实现代码

    public class KickoutSessionFilter extends OncePerRequestFilter { private ShiroSessionRepository shiroSessionRepository; public void setShiroSessionRepository(ShiroSessionRepository repository) { ...

    SpringBoot-JWT-Token:JWT令牌,Spring-Security

    在IT行业中,Spring Boot和Spring Security是两个非常重要的框架,它们在构建现代Web应用程序时起着核心作用。JWT(Json Web Token)则是一种安全的身份验证机制,被广泛应用于微服务架构和API授权。本篇文章将深入...

    spring MVC cors跨域实现源码解析

    5. `AbstractHandlerMapping`、`RequestMappingHandlerMapping`、`CorsInterceptor`、`PreFlightHandler`等:这些类在Spring MVC的请求处理链中起到了关键作用,如读取`@CrossOrigin`注解信息和从XML文件中解析跨域...

Global site tag (gtag.js) - Google Analytics