弹簧过滤器与拦截器的区别与联系
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(请求,响应);
}
}