文档章节

java web 过滤器跟拦截器的区别和使用

颖辉小居
 颖辉小居
发布于 2016/09/19 17:40
字数 1267
阅读 465
收藏 0

1、首先要明确什么是拦截器、什么是过滤器

1.1 什么是拦截器:

    拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。 
   在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。 
    谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈           Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。 

1.2.    拦截器的实现原理: 

大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。

1.3 什么是过滤器

过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:
①以常规的方式调用资源(即,调用servlet或JSP页面)。
②利用修改过的请求信息调用资源。
③调用资源,但在发送响应到客户机前对其进行修改。
④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。

1.4 Servlet过滤器的基本原理

在Servlet作为过滤器使用时,它可以对客户的请求进行处理。处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请求发送到目标为止。例如,某网站里有提交“修改的注册信息”的网页,当用户填写完修改信息并提交后,服务器在进行处理时需要做两项工作:判断客户端的会话是否有效;对提交的数据进行统一编码。这两项工作可以在由两个过滤器组成的过滤链里进行处理。当过滤器处理成功后,把提交的数据发送到最终目标;如果过滤器处理不成功,将把视图派发到指定的错误页面。

2、拦截器与过滤器的区别 : 

     1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
     2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。 
     3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
     4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。 
     5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

拦截器的代码实现(以struts2为例):
1、在xml文件中如何定义拦截器

<interceptors>
 <interceptor name="filterIPInterceptor"
                         class="com.xxxx.web.FilterIPActionInterceptor" />
<interceptor-stack name="filterIPStack">
<interceptor-ref name="defaultStack" />
                              
<interceptor-ref name="filterIPInterceptor" />
</interceptor-stack>
</interceptors>


2、怎么编写自定义拦截器 

public class FilterIPActionInterceptor extends AbstractInterceptor
{
    /** 日志控制. */
    private final Log log = LogFactory.getLog(getClass());
 
    /**
     * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
     */
    @Override
    @SuppressWarnings("unchecked")
    public String intercept(ActionInvocation invocation) throws Exception
    {
        String result = null;
        // 获得当前方法名.
        String methodName = invocation.getInvocationContext().getName();
        String currIp = null;
        try
        {
            if (invocation.getAction() instanceof PortletAction)
            {
                PortletAction action = (PortletAction) invocation.getAction();
                currIp = action.getRequest().getRemoteAddr();
            }
            String ip = ApplicationResource.getHotValue("ALLOW_CACHE_IP");
 
            if (StringUtils.isBlank(ip) || StringUtils.isBlank(currIp))
            {
                log.error("允许刷新的IP不存在或当前请求的IP非法.");
                throw new NoAllowIPException();
            }
            else
            {
                String[] ips = ip.split(",");
                boolean errorIp = true;
                for (String s : ips)
                {
                    if (s.equals(currIp))
                        errorIp = false;
                }
                // 判断IP
                if (errorIp)
                    throw new NoAllowIPException();
            }
            result = invocation.invoke();//调用被拦截的方法
        }
        catch (Exception e)
        {
            log.error("异常类名:" + invocation.getAction().getClass());
            log.error("异常方法:" + methodName, e);
            throw e;
        }
 
        return result;
    }
 
}

3、怎么编写过滤器
 
     1、在web.xml里面配置自定义的拦截器
     

  <filter>
<filter-name>Redirect Filter</filter-name>
<filter-class>com.xx.filter.RedirectFilter</filter-class>
</filter>
 
<filter-mapping>
<filter-name>Redirect Filter</filter-name>
<url-pattern>/xx/xx/*</url-pattern>
 
</filter-mapping>

    2、如何编写自定义的拦截器

public class RedirectFilter implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain filterChain) throws IOException, ServletException {
    // 获取URL
   Long startTime = null;
        if (log.isDebugEnabled())
        {
            startTime = System.currentTimeMillis();
        }
              HttpServletRequest httpRequest = (HttpServletRequest) request;
                          String url = httpRequest.getRequestURL().toString();
                      if (url == null || url.trim().length() == 0) {
                                    return;
                                                   }
                     if (url.indexOf(luceneCreateMapping) != -1
                                  || url.indexOf(luceneSearchMapping) != -1) {
                               doFilterForxxx(request, response, url);
                               } else {
                                     doxxxx(request, response, url);
                                    }
         if (log.isDebugEnabled())
        {
            long endTime = System.currentTimeMillis();
            Thread currentThread = Thread.currentThread();
            String threadName = currentThread.getName();
            log.debug("[" + threadName + "]" + "< "
                    + this.getClass().getName() + " " + url + " "
                    + (endTime - startTime) + " ms");
        }
// 激活下一个Filter
 filterChain.doFilter(request, response);
 
        }
}

 

本文转载自:

颖辉小居

颖辉小居

粉丝 35
博文 189
码字总数 80452
作品 0
东城
高级程序员
私信 提问
加载中

评论(2)

颖辉小居
颖辉小居
mybatis也有自己的拦截器,常在分页插件时使用
颖辉小居
颖辉小居
拦截器是struts的,过滤器是servlet的
过滤器(filter)与拦截器(Interceptor ) 差异性比较

1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客...

开源小菜鸟2333
2017/10/22
0
0
SpringBoot | 第七章:过滤器、监听器、拦截器

前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏高词汇、访问权限控制(URL级别)等业务需求。这些对于业务来说一般上是无关的,业务方是无需...

oKong
2018/07/19
0
0
Java个人技术知识点总结(框架篇)

框架篇 Struts1的运行原理 在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionServlet接收,ActionServlet在用户...

java架构
2018/11/08
0
0
在java中struts中拦截器的实现原理和作用?还有和过滤器的区别?

在java中struts中拦截器的实现原理和作用?还有和过滤器的区别?

秋秋儿33
2012/03/19
901
0
Java面试题之Struts2

1.简单的介绍一下Struts2 struts2框架框架是一个按照MVC设计模式设计的WEB层框架,是在Struts1和WebWork的技术基础上进行了合并的全新的框架 ,其全新的Struts2的体系结构,与Struts1的体系结...

年轻诠释我们的梦想_705b
2018/06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用kubeadm 搭建K8s集群

1. 参考官网 https://kubernetes.io/docs/setup/independent/install-kubeadm/

whhbb
29分钟前
2
0
Dubbo 3.0 !提升不止一点点!

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。 自去年 12 月开始,Dubbo 3.0 便已正...

编程SHA
29分钟前
2
0
提升不止一点点,Dubbo 3.0 预览版详细解读

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。更多用户信息,可以访问Dubbo @GitHub...

阿里云云栖社区
33分钟前
13
0
HanLP Analysis for Elasticsearch

基于 HanLP 的 Elasticsearch 中文分词插件,核心功能: 兼容 ES 5.x-7.x; 内置词典,无需额外配置即可使用; 支持用户自定义词典; 支持远程词典热更新(待开发); 内置多种分词模式,适合...

左手的倒影
55分钟前
1
0
spark部署之yarn模式

spark部署之yarn模式 hadoop-3.0.0集群搭建 配置相应环境 java环境 scala(可配可不配) hadoop环境 从官网下载spark 解压 配置 /conf/spark-env.sh export JAVA_HOME=/usr/java/jdk1.8.0_4...

jackmanwu
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部