弹簧过滤器与拦截器的区别与联系

1首先,什么是拦截器,什么是过滤器。

1.1什么是拦截器?

拦截器用在AOP(面向方面编程)中,在方法或字段被访问之前拦截它,然后在它之前或之后添加一些操作。拦截是AOP的一种实现策略。

Webwork中的中文文档解释为——拦截器是动态拦截动作调用的对象。它为开发人员提供了一种机制,可以定义在执行某个操作之前和之后要执行的代码,还可以在执行某个操作之前阻止它的执行。同时,它也提供了一种从动作中提取可重用部分的方法。

说到拦截器,还有一个词大家应该都知道——拦截器链(Struts2中称为拦截器栈)。拦截器链就是将拦截器按照一定的顺序连接成一个链。当访问被拦截的方法或字段时,拦截器链中的拦截器将按照之前定义的顺序被调用。

1.2.拦截器的实现原理:

大多数时候,拦截器方法是由代理调用的。Struts2的拦截器实现相对简单。当请求到达Struts2的ServletDispatcher时,Struts 2会查找配置文件,根据其配置实例化相关的拦截器对象,然后将它们串成一个列表,最后逐个调用列表中的拦截器。

1.3什么是滤镜?

过滤器是在服务器上运行的程序,在servlet或JSP页面之前运行。过滤器可以附加到一个或多个servlet或JSP页面,并且可以检查请求信息以进入这些资源。之后,过滤器可以做出以下选择:

①以常规方式调用资源(即调用servlet或JSP页面)。

②使用修改后的请求信息调用资源。

③调用资源,但在向客户端发送响应之前对其进行修改。

(4)停止资源调用,转到其他资源,返回特定的状态代码或生成替代输出。

1.4 Servlet过滤器的基本原理

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

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

1.拦截器基于java反射机制,过滤器基于函数回调。

2.拦截器不依赖于servlet容器,过滤器依赖于servlet容器。

3.拦截器只能处理动作请求,而过滤器可以处理几乎所有的请求。

4.拦截器可以访问动作上下文和值堆栈中的对象,但是过滤器不能。

5.在动作的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

拦截器的代码实现(以struts2为例);

1.如何在xml文件中定义拦截器

& lt拦截器& gt

& lt拦截器名称="filterIPInterceptor "

class = " com . xxxx . web . filteripactioninterceptor "/& gt;

& ltinterceptor-stack name = " filterIPStack " & gt;

& ltinterceptor-ref name = " default stack "/& gt;

& ltinterceptor-ref name = " filterIPInterceptor "/& gt;

& lt/interceptor-stack & gt;

& lt/interceptors & gt;

2.如何停止编写自定义拦截器?

公共类FilterIPActionInterceptor扩展AbstractInterceptor

{

/* *日志控制。*/

私有最终日志Log = Log factory . get Log(getClass());

/**

* @ see com . open symphony . xwork 2 . interceptor . abstract interceptor # intercept(com . open symphony . xwork 2 . action invocation)

*/

@覆盖

@SuppressWarnings("未选中")

公共字符串截获(ActionInvocation调用)引发异常

{

字符串结果= null

//获取当前方法名。

string method name = invocation . getinvocationcontext()。getName();

String currIp = null

尝试

{

if(invocation . getaction()PortletAction的instanceof)

{

portlet action action =(portlet action)invocation . get action();

currIp = action.getRequest()。getremote addr();

}

string IP = application resource . get hot value(" ALLOW _ CACHE _ IP ");

if(string utils . is blank(IP)| | string utils . is blank(currIp))

{

Log.error("允许刷新的IP不存在或当前请求的IP不合法。");

抛出新的NoAllowIPException();

}

其他

{

String[] ips = ip.split(",");

boolean errorIp = true

for(字符串s : ips)

{

if (s.equals(currIp))

errorIp = false

}

//判断IP

if (errorIp)

抛出新的NoAllowIPException();

}

result = invocation . invoke();//调用截获的方法。

}

捕捉(例外e)

{

Log.error("异常类名:"+invocation.getaction()。getclass());

Log.error("异常方法:"+methodName,e);

扔e;

}

返回结果;

}

}

3.如何编写过滤器

1.在web.xml中配置自定义拦截器

& lt过滤器& gt

& ltfilter-name & gt;重定向过滤器& lt/filter-name & gt;

& ltfilter-class & gt;com . xx . filter . redirect filter & lt;/filter-class & gt;

& lt/filter & gt;

& lt过滤器映射& gt

& lt过滤器名称& gt重定向过滤器& lt/filter-name & gt;

& lturl模式& gt/xx/xx/* & lt;/URL-pattern & gt;

& lt/filter-mapping & gt;

2.如何编写自定义拦截器?

公共类RedirectFilter实现筛选器{

public void do filter(servlet request请求,ServletResponse响应,

FilterChain filterChain)引发IOException,ServletException {

//获取URL

长startTime = null

if (log.isDebugEnabled())

{

start time = system . current time millis();

}

http servlet request http request =(http servlet request)请求;

string URL = http request . getrequesturl()。toString();

if (url == null || url.trim()。length() == 0) {

返回;

}

if(URL . index of(luceneCreateMapping)!= -1

| | URL . index of(luceneSearchMapping)!= -1) {

doFilterForxxx(请求、响应、URL);

}否则{

doxxxx(请求、响应、URL);

}

if (log.isDebugEnabled())

{

long end time = system . current time millis();

thread currentThread = thread . current thread();

string threadName = current thread . getname();

log . debug("["+thread name+"]"+" & lt;

+ this.getClass()。getName() + " " + url +" "

+(end time-start time)+“ms”);

}

//激活下一个过滤器。

filterChain.doFilter(请求,响应);

}

}