zoukankan      html  css  js  c++  java
  • OncePerRequestFilter作用(转)

    在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.     }  

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

  • 相关阅读:
    倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何把FBD功能块转换成ST语言
    揭秘一个操作灰色关键词牟取暴利的案例
    [原创汉化] 价值990美元的顶级专业数据恢复软件O&O DiskRecovery 11(技术员版)汉化绿色版
    list集合如何对里面的元素进行排序
    jquery datables ajax分页后的点击事件无效是怎么回事
    阿里云自动快照有什么用,如何设置?
    php后台管理员权限相关表结构
    服务器上装了安全狗后远程链接不上怎么解决
    Ehcache配置参数简介
    Spring+EhCache缓存实例
  • 原文地址:https://www.cnblogs.com/cornucopia/p/4502664.html
Copyright © 2011-2022 走看看