注:文章整理自知乎大牛以及百度网友(电脑网络分类达人 吕明),特此感谢! 
一、过滤器 
1.什么是过滤器?

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

2.Servlet过滤器的基本原理:

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

3.过滤器:只想要在一堆东西里面选个B: 

4.示例代码

在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>
如何编写自定义的过滤器
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); }
}
示例2
// 填充100个带有随机字母标签的球
List<String> array = new ArrayList<>();
Random r = new Random();
String[] balls = new String[]{"A", "B", "C"};
for (int i = 0; i < 100; i++)
array.add(balls[r.nextInt(3)]); // 只拿出B的来。不明白的自行学习Java 8
array = array.stream().filter(ball -> ball.equals("B")).collect(Collectors.toList()); 作者:知乎用户
链接:https://www.zhihu.com/question/35225845/answer/61876681
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、拦截器 
1.什么是拦截器?

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

2.拦截器的实现原理:

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

3.拦截器:把水流变小点,把鱼都拦住!顺便发个电: 

4.示例代码

在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>
怎么编写自定义拦截器
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;
} }
示例2
作者:知乎用户
链接:https://www.zhihu.com/question/35225845/answer/61876681
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 class River {
// 流量
int volume; // 总鱼数
int numFish;
} class PowerGenerator {
double generate (int volume) {
// 假设每一百立方米水发一度电
return volume / 100;
}
} interface Interceptor {
void intercept (River river);
} class SomeInterceptor implements Interceptor {
PowerGenerator generator = new PowerGenerator(); @Override
public void intercept (River river) {
// 消耗了1000立方米水来发电
int waterUsed = 1000; // 水量减少了1000。请不要跟我讨论水电站原理的问题,
// 我就那么一比方
river.volume -= waterUsed; // 发电
generator.generate (waterUsed); // 拦截所有的鱼
river.numFish = 0;
}
} class RiverController {
Interceptor interceptor; void flow(River river) {
// 源头积累下来的水量和鱼
river.volume += 100000
river.numFish += 1000 // 经过了大坝
interceptor.intercept(river); // 下了点雨
river.volume += 1000
} void setInterceptor (Interceptor interceptor) {
this.interceptor = interceptor
}
} class Main {
public static void main (String args[]) {
RiverController rc = new RiverController;
Interceptor inter = new SomeInterceptor(); // 这一步通常叫做控制反转或依赖注入,其实也没啥子
rc.setInterceptor(inter); rc.flow(new River());
}
}


拦截器与过滤器的区别 :

 1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次拦截器的代
码实现。
6. Filter基于回调函数,我们需要实现的filter接口中doFilter方法就是回调函数,而interceptor则基于
java本身的反射机制,这是两者最本质的区别。
7. Filter是依赖于servlet容器的,即只能在servlet容器中执行,很显然没有servlet容器就无法来回调
doFilter方法。而interceptor与servlet容器无关。
8. Filter的过滤范围比Interceptor大,Filter除了过滤请求外通过通配符可以保护页面,图片,文件等等,
而Interceptor只能过滤请求。
9. Filter的过滤例外一般是在加载的时候在init方法声明,而Interceptor可以通过在xml声明是guest请求还
是user请求来辨别是否过滤。

三、监听器 
1.监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程,这就要用到监听器。 

2.示例代码

作者:知乎用户
链接:https://www.zhihu.com/question/35225845/answer/61876681
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 // 监听器
interface BedListener {
// 监听器在参数中收到了某个事件,而这个事件往往是只读的
// 监听器的方法名通常以"on"开头
void onBedSound (String sound);
} class Neighbor {
BedListener listener; // 依然是所谓控制反转
setListener (BedListener listener) {
this.listener = listener;
} void doInterestingStuff () {
// 根据当地法律法规,部分内容无法显示 // 将事件发送给监听器
listener.onBedSound("嘿咻");
listener.onBedSound("oyeah");
}
} class Main {
public static void main (String args[]) {
Neighbor n = new Neighbor();
n.setListener (sound -> generatePower());
n.doInterestingStuff();
} private static void generatePower() {
// 根据当地法律法规,部分内容无法显示
}
}

java web 过滤器跟拦截器的区别和使用的更多相关文章

  1. Java中过滤器和拦截器的区别

    1.拦截器是基于java反射机制的,而过滤器是基于函数回调的. 2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器. 3.拦截器只对action起作用,而过滤器几乎可以对所有请求起 ...

  2. struts2 过滤器和拦截器的区别和使用

    java web 过滤器和拦截器的区别和使用  1.1 什么是拦截器:      拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然 ...

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

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

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

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

  5. JavaWeb过滤器.监听器.拦截器-原理&区别-个人总结

    对比项 拦截器 过滤器 机制 反射机制 函数回调 是否依赖servlet容器 是 否 请求处理 只能对action请求起作用 几乎所有的请求起作用 对action处理 可以访问action上下文.值栈 ...

  6. JavaWeb过滤器.监听器.拦截器-原理&区别(转)

    1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...

  7. spring过滤器和拦截器的区别和联系

    一 简介 (1)过滤器: 依赖于servlet容器,是JavaEE标准,是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理.在实现上基于函数回调,可 ...

  8. spring boot 过滤器、拦截器的区别与使用

    原文:https://blog.csdn.net/heweimingming/article/details/79993591 拦截器与过滤器的区别: 1.过滤器和拦截器触发时机不一样,过滤器是在请求 ...

  9. Java Web 中 过滤器与拦截器的区别

    过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法u ...

随机推荐

  1. 每日英语:When The Boss Works Long Hours, Do We All Have To?

    The problem: Every night, your workaholic boss is still glued to the computer when you need to leave ...

  2. Spark(Hive) SQL中UDF的使用(Python)【转】

    相对于使用MapReduce或者Spark Application的方式进行数据分析,使用Hive SQL或Spark SQL能为我们省去不少的代码工作量,而Hive SQL或Spark SQL本身内 ...

  3. 【Android】Intent解读

    Intent 的作用 Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯. 比如说调用startActivity()来启 ...

  4. AJAX开发技术

    AJAX技术 AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML),AJAX并不是一项新的技术,它产生的主要目的是用于页面的局部刷新,从之前的代 ...

  5. 微服务之springCloud-docker-feign-hystrix(六)

    简介 上一节我们讨论feign的配置,这节我们讨论一下,feign+hystrix调用生产者时,进行容错处理 一.创建模块(microservice-consumer-movie-feign-with ...

  6. 越狱机器SSH安装与使用

    SSH安装html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scroll { ...

  7. centos7 安装oracle jdk 与openjdk 实现切换

    1. 分别安装oraclejdk 与openjdk #下载安装oraclejdk rpm -ivh --prefix=/usr.java/java1.8 ***.rpm #安装openjdk su - ...

  8. [ntp]查看ntp服务器的连接情况

    转自:http://www.cnblogs.com/liuyou/archive/2012/07/29/2614338.html 命令和工具 # watch ntpq -p # ntpq -p, /e ...

  9. Android—— Animation动画(很详细)

    链接: http://www.360doc.com/content/13/0102/22/6541311_257754535.shtml http://www.cnblogs.com/aimeng/a ...

  10. [数据结构]迪杰斯特拉(Dijkstra)算法

    基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点vs(即从顶点vs开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点,而U则是记录还未求出最短路径的顶点(以及 ...