过滤器和拦截器的相似之处就是拦截请求,做一些预处理或者后处理。

而过滤器和拦截器的区别在于过滤器是相对HTTP请求而言的,而拦截器是相对Action中的方法的。

过滤器:访问web服务器的时候,对一个请求,我们可以设置请求编码,设置请求参数,设置其是否能访问某个页面,设置相应编码等。

拦截器:访问web服务器的时候,在你调用的方法前做一个拦截,加上我想要的任意操作。比喻记录操作日志,加上某个特定业务(AOP)。

1、过滤器

过滤器需要做两部分的工作:Filter过滤类、web.xml配置

Filter类部分:

package com.chanshuyi.servlet;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
//import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; /**
* Test Servlet Filter
* @author chenyr
*/
//@WebFilter(filterName = "myfilter", urlPatterns = {"/*.*"})
//你可以通过这段注释来声明这个Filter,从而不用在web.xml文件中配置,但你用的Servlet版本必须是3.0以上
public class MyServletFilter implements Filter { /** Filter Config Info **/
private FilterConfig config; public void init(FilterConfig config) throws ServletException {
this.config = config;
} public void destroy() {
this.config = null;
} public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//-------- Preprocess --------
long before = System.currentTimeMillis();
System.out.println("Begin filtering...");
HttpServletRequest hrequest = (HttpServletRequest)request;
System.out.println("Intercept the user request address:" + hrequest.getServletPath()); //-------- Do the Servlet --------
chain.doFilter(request, response); //-------- afterprocess --------
long after = System.currentTimeMillis();
System.out.println("End filtering...");
System.out.println("Redirect To:" + hrequest.getRequestURI() + " Time Cost:" + (after - before));
}
}

web.xml部分:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.chanshuyi.servlet.MyServletFilter</filter-class>
</filter> <filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

2、拦截器

Struts的拦截器本质上还是通过过滤器来实现的。

拦截器实现需要做两部分的工作:Interceptor过滤类、struts.xml配置

拦截器类:

package com.chanshuyi.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; @SuppressWarnings("serial")
public class MyInterceptor extends AbstractInterceptor { private String name; public void setName(String name) {
this.name = name;
} @Override
public String intercept(ActionInvocation invocation) throws Exception { //get the target action
//LoginAction action = (LoginAction)invocation.getAction();
System.out.println(name + "Interceptor begin to work ...");
long startMill = System.currentTimeMillis(); //execute the target action method
String result = invocation.invoke(); long endMill = System.currentTimeMillis();
System.out.println(name + "Interceptor ends, time cost:" + (endMill - startMill));
System.out.println("result is : " + result); return result;
}
}

你可以通过实现Interceptor接口来实现拦截器。但是Java为我们提供了AbstractInterceptor类,通过实现AbstractInterceptor类可以让我们减少编码(因为AbstractInterceptor已经帮我们实现了init()/destory()方法,我们只需再实现interceptor方法即可)

struts.xml配置部分:

<struts>
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="loginInter" class="com.chanshuyi.interceptor.MyInterceptor">
<param name="name">[默认的拦截器名字]</param>
</interceptor>
</interceptors> <action name="login" class="com.chanshuyi.action.LoginAction" method="execute">
<result name="success">/hello.jsp</result>
<result name="login">/hello.jsp</result> <interceptor-ref name="defaultStack"/>
<interceptor-ref name="loginInter">
<param name="name">[修改后的拦截器名字]</param>
</interceptor-ref>
</action>
</package>
</struts>

MARK CHENYR (这里需要补充)

3、只拦截部分Action部分方法的拦截器

通过继承AbstractInterceptor的子类:MethodFilterInterceptor类,可以实现对Action中方法级的过滤。

它与继承AbstractInterceptor实现过滤在代码上的不同在于:

1).需要继承的是MethodFilterInterceptor类

2).需要实现的是doInterceptor方法,而不是interceptor方法

3).可以通过setExcludeMethod/setIncludeMethod方法或配置文件的方式实现方法的过滤

拦截器部分代码(将intercept方法换成doIntercept即可):

@SuppressWarnings("serial")
public class CopyOfMyInterceptor extends MethodFilterInterceptor { private String name; public void setName(String name) {
this.name = name;
} @Override
public String doIntercept(ActionInvocation invocation) throws Exception { //get the target action
//LoginAction action = (LoginAction)invocation.getAction();
System.out.println(name + "Interceptor begin to work ...");
long startMill = System.currentTimeMillis();      //直接调用setExcludeMethod/setIncludeMethod方法给excludeMethod/includeMethod属性赋值。这与用配置文件赋值是一样的 //execute the target action method
String result = invocation.invoke(); long endMill = System.currentTimeMillis();
System.out.println(name + "Interceptor ends, time cost:" + (endMill - startMill));
System.out.println("result is : " + result); return result;
}
}

通过配置文件实现对方法的过滤:

<struts>
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="loginInter" class="com.chanshuyi.interceptor.MyInterceptor">
<param name="name">[默认的拦截器名字]</param>
</interceptor>
</interceptors> <action name="login" class="com.chanshuyi.action.LoginAction" method="execute">
<result name="success">/hello.jsp</result>
<result name="login">/hello.jsp</result> <interceptor-ref name="defaultStack"/>
<interceptor-ref name="loginInter">
<param name="name">[修改后的拦截器名字]</param>
<!-- 多个方法用英文逗号隔开 -->
<param name="excludeMethods">execute</param>
<!-- 通过配置文件赋值,本质上是给继承了MethodFilterInterceptor的CopyOfMyInterceptor类的excludeMethods属性复制。所以你也可以不在这里复制,而直接在CopyOfMyInterceptor类中用setExcludedMethod/setIncludeMethod赋值 -->
</interceptor-ref>
</action>
</package>
</struts>

4、关于过滤器和拦截器的执行顺序

在一般情况下,过滤器和拦截器都是先配置先执行的。

下面用过滤器的一个例子说明:

web.xml部分代码:

<!-- 第一个过滤器 -->
<filter>
<filter-name>filter1</filter-name>
<filter-class>filter.Filter1</filter-class>
</filter>
<filter-mapping>
<filter-name>filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 第二个过滤器 -->
<filter>
<filter-name>filter2</filter-name>
<filter-class>filter.Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>filter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Filter1类的关键代码:

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
System.out.println("filter1");
chain.doFilter(request, response);
System.out.println("filter1 go back");
} catch (Exception e) {
e.printStackTrace();
}
}

Filter2类与Filter1类一样,只是输出内容变成了“filter2”以及“filter2   go back”。

运行结果为:

filter1
filter2
filter2 go back
filter1 go back

可以看出,过滤器和拦截器的执行顺序是先定义先执行,并且执行是类似于堆栈的先进后出的执行顺序。  

5、关于过滤器和拦截器的思考

在说拦截器和过滤器之前,先说这两者的几点区别:

1.过滤器可以对所有HTTP请求进行拦截,但拦截器只能对Action请求进行拦截

2.过滤器是Servlet中的概念,拦截器是Struts中的概念

在Struts还没有出来的时候,拦截器这个概念是不存在的。在Struts出来之后,拦截器也来了。拦截器是通过Servlet来实现的,拦截器对过滤器进行了一层封装,使Struts框架更加好用。

在使用了Struts框架的项目中,更多人直接使用拦截器,过滤器的概念就被弱化了。这是我的一些理解。因此在使用了Struts的项目中,你可以直接使用拦截器对所有Action请求进行拦截,对他们进行权限控制。

但拦截器不能拦截直接访问的页面,那这些页面如何保障权限的控制呢?答案是将页面房在WEB-INF目录下(WEB-INF目录下的文件不能通过客户端直接访问),只将少数必要的文件放在Web-Root目录,这样就可以实现这些页面的安全。

总的来说,如果你的项目使用了Struts,那么你可以直接用Struts的拦截器实现权限控制等。

但如果你的项目是用纯Servlet写的,那么你只能用过滤器实现了。

===================== 相信美好的事情终会发生 ====================

struts.xml文件中拦截器配置集锦

<!-- 配置拦截器 -->
<interceptor name="interceptor1" class="classRoute"/>
<interceptor name="interceptor1" class="classRoute">
<param name="paraName">Param Value</param>
</interceptor>
<!-- 拦截器栈 -->
<interceptor-stack name="stackName">
<interceptor name="interceptor1" class="classRoute"/>
<interceptor-ref name="interceptorName">
<param name="paraName">Param Value</param>
</interceptor-ref>
</interceptor-stack>
<!-- 使用拦截器 -->
<action name="" class="" method="">
<result>...</result>
<!-- 一定要加上Struts的默认拦截器 -->
<interceptor-ref name="defaultStack"/>
<!-- 使用自己的拦截器 -->
<interceptor-ref name="myInterceptor"/>
</action>
<!-- 设置默认拦截器 -->
<package>
<interceptors>...</interceptors>
<!-- 设置默认拦截器 -->
<default-interceptor-ref name=""></default-interceptor-ref>
<action>...</action>
</package>

  

  

J2EE中的过滤器和拦截器的更多相关文章

  1. Java中的过滤器,拦截器,监听器---------简单易懂的介绍

    过滤器: 过滤器其主要特点在于:取你需要的东西,忽视那些不需要的东西!在程序中,你希望选择中篇文章中的所有数字,你就可以针对性的挑选数字! 拦截器: 拦截器其主要特点在于:针对你不要的东西进行拦截,比 ...

  2. springboot中使用过滤器、拦截器、监听器

    监听器:listener是servlet规范中定义的一种特殊类.用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件.监听域对象的属性发生 ...

  3. Struts2中过滤器和拦截器的区别

    拦截器和过滤器的区别: 1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而 ...

  4. spring中的监视器,过滤器,拦截器

    1.监视器 (1)首先监视器是观察者模式的实现,在我之前的博客中有关于监视器模式的解释.监视器相当于观察者 (2)我们在springMvc中最常见的监视器 ContextLoaderlistener ...

  5. 过滤器、拦截器和AOP的分析与对比

    目录 一.过滤器(Filter) 1.1 简介 1.2 应用场景 1.3 源码分析 二.拦截器(Interceptor) 2.1 简介 2.2 应用场景 2.2 源码分析 三.面向切面编程(AOP) ...

  6. Struts2之过滤器和拦截器的区别

    刚学习Struts2这个框架不久,心中依然有一个疑惑未解那就是过滤器和拦截器的区别,相信也有不少人跟我一样对于这个问题没有太多的深入了解 那么下面我们就一起来探讨探讨 过滤器,是在java web中, ...

  7. Struts2 过滤器与拦截器

    学习Struts2时,发现有过滤器和拦截器,他们貌似都是一样的功能,但是为什么会有2个不同的名称呢?肯定是有区别的,所以打算自己整理一下. 过滤器,是在java web中,你传入的request,re ...

  8. springBoot之配置文件的读取以及过滤器和拦截器的使用

    前言 在之前的学习springBoot中,成功的实现了Restful风格的基本服务.但是想将之前的工程作为一个项目来说,那些是仅仅不够的.可能还需要获取自定义的配置以及添加过滤器和拦截器.至于为什么将 ...

  9. Servlet 过滤器、拦截器、监听器以及文件上传下载

    在学习之初,总是对过滤器.拦截器.监听器这三个搞不清楚,现在进行一些记录,方便大家交流,也为了提高自身的学习能力! 如果想要了解这三个的作用,首先对servlet流程进行熟悉了解,servlet是客户 ...

随机推荐

  1. 我的前端架构(jquery)汇总

    目录 我的前端架构之一--页面作用域 我的前端架构之二--统一扩展Js方法 我的前端架构之三 -- 页面规范 我的前端架构之四 -- UI控件 我的前端架构之五 -- 一些方案实现 判断对象是否是 e ...

  2. 用OC实现一个栈:结合单链表创建动态栈

    一.介绍 栈是一种数据存储结构,存储的数据具有先进后出的特点.栈一般分为动态栈和静态栈. 静态栈比较好理解,例如用数组实现的栈.动态栈可以用链表来实现. 方式:固定base指针,每次更改top指向入栈 ...

  3. HTML5 Canvas 为网页添加文字水印

    <!DOCTYPE html> <html> <body> <canvas id=" style="border:1px solid #d ...

  4. EF-入门操作

    EntityFramework Core 理解 DbContext :数据库 DbSet: 数据库表 Model : 数据行 IQueryable<Model> 查询结果集合 Lamada ...

  5. python3的reload(sys)

    import sys reload(sys) sys.setdefaultencoding(‘utf-8’) 以上是python2的写法,但是在python3中这个需要已经不存在了,这么做也不会什么实 ...

  6. Netty与RPC

    一.Netty原理 Netty是一个高性能.异步事件驱动的NIO框架,基于Java NIO提供的API实现.它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都 ...

  7. 再来五道剑指offer题目

    再来五道剑指offer题目 6.旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  8. Python图像处理库Pillow常用使用方法

    PIL(Python Imaging Library)是Python一个强大方便的图像处理库,只支持到Python2.7.Pillow是PIL的一个派生分支,在Python3中用Pillow代替PIL ...

  9. ABP进阶教程3 - 优化编辑

    点这里进入ABP进阶教程目录 我们尝试在新增/编辑界面增加一个下拉框用来代替输入框编辑Status 添加实体 打开领域层(即JD.CRS.Core)的Entitys目录 //用以存放实体对象添加一个类 ...

  10. 解决汉化pycharme之后设置打不开的问题

    首先进入安装pycharme目录下lib目录下,将汉化包移出去,只留下英文包 然后打开pycharme即可打开设置 在你改完设置之后,可以再将汉化包放进来 英文包:https://pan.baidu. ...