Struts 2.0系列之七---拦截器(Interceptor)
struts2拦截器--将用户操作日志存入数据库
struts2拦截器--将用户操作日志存入数据库第一篇:struts2拦截器--将用户操作日志存入数据库struts2拦截器--将用户操作日志存入数据库1.建表,如下所示:2.新建OperationLogModel.java,其具有上述属性。
3.自动生成PO4.在struts.xml中配置拦截器:5.如下例子中的用户登录和修改密码,要在相应xml文件中加入,即:indexchangePasswordPre6.在项目中新建文件夹log,在其下新建类LogInterceptor .java,如下:package com.bfw.crms.log; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import ng.StringUtils; import org.apache.log4j.Logger; import org.apache.struts2.ServletActionContext; import com.bfw.crms.action.BulletinAction; import com.bfw.crms.action.SystemAction; import com.bfw.crms.model.EmployeeModel; import com.bfw.crms.model.OperationLogModel; import com.bfw.crms.po.OperationLog; import com.bfw.crms.util.BeanUtil; import com.bfw.crms.util.DateTimeUtil; import com.ninetowns.framework.dao.ObjectDao; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;@SuppressWarnings("serial")public class LogInterceptor extends AbstractInterceptor{ private String logName;private String logContent;protected Logger log = Logger.getLogger(getClass()); protected HttpSession getSession(){return getRequest().getSession();}protected HttpServletRequest getRequest(){return ServletActionContext.getRequest();}public void init() {}private ObjectDao objectDao = null;public ObjectDao getObjectDao(){return objectDao;}public void setObjectDao(ObjectDao objectDao){this.objectDao = objectDao;}@Overridepublic String intercept(ActionInvocation ai) throws Exception {Object action= ai.getAction();String method= ai.getProxy().getMethod();try{if(StringUtils.isBlank(method)) method = "method";EmployeeModel sysUser (EmployeeModel)this.getSession().getAttribute("employee");String userName = "";if(sysUser!=null) userName = sysUser.getName();=String currentTime = DateTimeUtil.getDateTime();String logContentHead = "用户"+userName+currentTime;ai.invoke();//执行被拦截actionif (action instanceof BulletinAction) {if(method.equals("save")){logName = "保存部门";logContent = logContentHead+"保存部门:"+ai.getStack().findValue("Name");(logContent);addSysLog(logName,logContent);}if(method.equals("delete")){logName = "删除部门";logContent = logContentHead +""+((String[])(ai.getStack().findValue("flag_id"))).length+"条部门信息";(logContent);addSysLog(logName,logContent);}}if (actioninstanceof SystemAction) {if(method.equals("login")){logName = "登录系统";logContent = logContentHead;(logContent);addSysLog(logName,logContent);}if(method.equals("changePassword")){logName = "修改密码";logContent = logContentHead +"删除1条单位信息";(logContent);addSysLog(logName,logContent);}}}catch(Exception e){e.printStackTrace();}return Action.SUCCESS;}/*** 插入系统日志 model2po()* @param logName* @param logContent*/删除private void addSysLog(String logName,String logContent){ OperationLogModel operationModel = new OperationLogModel();OperationLog operationPO = new OperationLog();operationModel.setOperation(logContent);BeanUtil.model2po(operationModel, operationPO);this.getObjectDao().saveObject(operationPO);}} OK第二篇:Struts2中的拦截器与过滤器学习拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法,比如动态代理就是拦截器的简单实现,过滤器是在java web中,你传入的request,response 提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do 的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符。
struts2_拦截器(Interceptors)
拦截器的工作原理如上图,每一个Action请求都包装在一系列的拦截器的内部。
拦截器可以在Action执行直线做相似的操作也可以在Action执行直后做回收操作。
每一个Action既可以将操作转交给下面的拦截器,Action也可以直接退出操作返回客户既定的画面。
如何自定义一个拦截器?自定义一个拦截器需要三步:1 自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。
2 在strutx.xml中注册上一步中定义的拦截器。
3 在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。
Interceptor接口声明了三个方法:public interface Interceptor extends Serializable {void destroy();void init();String intercept(ActionInvocation invocation) throws Exception; }Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,使用这个方法可以给拦截器类做必要的初始话操作。
Destroy方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。
Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。
如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。
另外AbstractInterceptor提供了一个简单的Interceptor的实现,这个实现为:public abstract class AbstractInterceptor implements Interceptor {public void init() {}public void destroy() {}public abstract String intercept(ActionInvocation invocation) throws Exception;}在不需要编写init和destroy方法的时候,只需要从AbstractInterceptor继承而来,实现intercept方法即可。
07Struts 2的基石——拦截器(Interceptor)
Struts 2的基石——拦截器(Interceptor)/max/category/16130.html首先,要跟大家道个歉,前一阵子为给客户个一个DEMO,忙得不可开交,所以很久没有更新Blog。
提到这个DEMO我想顺便跟大家分享一下心得——如果大家希望快速开发,一个类似Struts 2这样的简单方便的WEB框架必不可少。
我们在开发DEMO使用的还是Struts 1.2.8,而且没有不使用任何EL(表达式语言),导致页面出现无数类似“<%= ((Integer)request.getAttribute("xx")).intValue()%6 %>”的代码。
Struts 1.x的Form Bean的麻烦使得有部分同事直接使用request.getParameter(String arg),继而引入另一种麻烦。
诸如此类的问题,在DEMO这样时间紧迫的项目凸显了Struts 1.x对快速开发的无能为力。
不过没办法,由于我们项目中的几个资深员工除了Struts 1.x外,对其它的WEB框架似乎不大感兴趣。
言归正传,Interceptor(以下译为拦截器)是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。
什么是拦截器拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
拦截是AOP的一种实现策略。
在 Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。
它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。
同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。
拦截器概述
拦截器内容提要拦截器(Interceptor)是动态拦截Action调用的对象,类似于Servlet中的过滤器。
在执行Action的execute()方法之前,Struts 2会首先执行在struts.xml中引用的拦截器。
所以说,拦截器提供了一种机制,使开发者可以在一个Action前后执行需要的代码,可以在一个Action执前阻止其执行,也可以在Action执行后做一些相应的工作,同时还提供一种可以提取Action中可重用部分的方式。
拦截器是Struts 2框架的基石,许多功能的实现都是构建在拦截器的基础之上的,例如文件的上传与下载、国际化、类型转换和数据校验等,并且Struts 2还提供内建拦截器,例如timer和params等,这些拦截器可完成框架的大部分任务。
学习目标理解拦截器的工作原理理解拦截器在Struts 2中的功能熟练掌握在Struts 2框架中配置拦截器的方法掌握拦截器的使用方法熟练掌握自定义拦截器的方法掌握拦截器中方法的过滤掌握内建拦截器1 拦截器简介拦截是AOP(Aspect-Oriented Programming,面向切面编程)的一种实现策略,如果说面向对象编程是将需求功能划分为不同的、相对独立的和封装良好的类,并使它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系,那么面向切面编程则是将通用需求功能从不相关的类中分离出来,使得很多类共享一个行为,一旦发生变化,不必修改很多类,只需修改这个行为即可。
Struts 2拦截器体系正是应用了AOP设计哲学,可以动态拦截Action调用的对象,开发者只需要提供拦截器的实现类,并将其配嚣在struts.xml文件中即可。
1.1 拦截器工作原理在通常情况下,拦截器都是通过代理的方式调用的。
当请求到达Struts 2的ServletDispatcher(Web HTTP请求的调度器,所有对Action的请求都将通过ServletDispatcher调用)时,Struts 2会查找配置文件,并根据配置实例化相对的拦截器对象,然后将这些对象串成一个列表(1ist),最后逐个调用列表中的拦截器,如图1-1所示。
Struts2的拦截器总结
Struts2 中的拦截器和servelt 中的过滤器是非常的相似的。
如果学过过滤器的话,肯定能够感觉的到,尽管有些微的不同。
可是struts2的拦截器到底如何使用呢,为什么会有这些配置呢?接下来一一来看。
过滤器和拦截器是非常相似的,过滤器public interface Filter 接口里面有三个方法:∙init(FilterConfig filterConfig),∙destroy(),∙doFilter(ServletRequest request, ServletResponse response, FilterChain chain), 这里面的doFilter() 方法是最重要的,在struts2 中String intercept(ActionInvocation invocation)就相当于此方法。
如何完成一个拦截器呢?在struts2 中要实现一个接口这个接口是什么呢?在哪呢?,是否在哪听说过?是webwork 是我们以前听的最多的关于拦截器的框架,struts2 用了其中一个核心的东西,这个东西在是什么呢?是xwork 。
恩,有了它才可以拦截,好了我们在哪找呢?在com.opensymphony.xwork2.interceptor 中找,里面有个Interceptor 这是个接口,里面也有三个方法,有init,destroy 和intercept 三个方法,而在struts2 里面的所有的拦截器都继承这个接口!为了看这些是怎么实现的,加入了一些打印!将上面的配置整合起来就是:这样就可以让Aciton 被拦截了,到此,好了,可以运行程序了:输出结果是:启动服务器init 被打出运行后提交action 输出intercept这个就是初步的一个拦截器。
=======在此可能出现一个问题,是什么呢?如果就我们做的注册程序而言,可以想一下,有数据转换,有数据校验,以前当转换和校验不符合的时候,点击提交,会提示相关错误信息,然而,此时当转换和校验依然不符合要求时,点击提交,却不会提示错误信息,为什么呢?====当然你答对了,这些功能都包含在struts2的默认拦截器中,这里没执行是被添加的拦截器myinterceptor取代了。
Struts2拦截器和监听器
Struts2拦截器和监听器第一种方法:直接implements实现com.opensymphony.xwork2.interceptor.InterceptorJava代码第二种方法直接extends com.opensymphony.xwork2.interceptor.AbstractInterceptor 这种方法是少了destroy,init方法Java代码第三种方法直接extends com.opensymphony.xwork2.interceptor.MethodFilterInterceptor这种方法能对Action里面的方法级进行控制,是否执行这个方法Java代码然就是配置Xml代码里面分interceptor和interceptor-stackstack也能引用stackdefault-interceptor-ref表示Action如果不指定interceptor就用这个default的extends="struts-default"表示这个XML文件是extends 另一个xml的,名字叫struts-default在这个XML中,配置了一个常用的interceptor可以去Core包中找到这个XMLinterceptor配置很灵活的。
如果要写自己的interceptor就要把<interceptor-ref name="defaultStack"></interceptor-ref>默认的给加上,当然也可以自己配置。
interceptor的参数Xml代码这个是因为MethodFilterInterceptor 里有这两个成员变量,如果你自己的interceptor要带参数的话就要相应的Action里面写到成员变量,并加上get,set方法Java代码监听器首先要实现com.opensymphony.xwork2.interceptor.PreResultListener类并重写里面的方法beforeResultJava代码然后再在拦截器里面调用Java代码监听器是在这个拦截器完成别的拦截器之后调用的struts2 Action获得HttpSession,HttpServletRequest,HttpSevletResponse的方法非IOC方式这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及org.apache.struts2.ServletActionContext类Java代码主要是这两个类com.opensymphony.xwork2.ActionContext和org.apache.struts2.ServletActionContext都对request等进行了大量的封装,直接调用方法就可以获和更好一点的IOC方式action类实现ServletRequestAware接口,并新建一个HttpServletRequest requestJava代码}这些获得HttpServletRequest等对象需要implments的接口都在org.apache.struts2.interceptor下面如Apllication的是ApplicationAware如HttpSession的是SessionAware(struts2的Session都被封装成Map了)如HttpServletRequest的是ServletRequestAware如HttpServletResponse的是ServletResponseAware。
拦截器
ConfigurationProvider&Configuration ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主 要是尤其实现类 XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider 来解析。
拦截器就是AOP(AspectOriented Programming)的 一种实现。(AOP是指用于 在某个方法或字段被访问之 前,进行拦截然后在之前或 之后加入某些操作(与业务逻 辑无关的操作:文件上传, 防止表单重复提交,日 志。。)
ActionMapper其实是HttpServletRequest和Action调用请求的一个映射 ActionProxy作用是如何取得Action,ActionInvocation的作用是如何 执行Action,拦截器的功能就是在ActionInvocation中实现的。 ConfigurationProvider就是Struts2中配置文件的解析器
ActionMapper ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了 Action对于Request等 java Servlet类的依赖。Struts2中它的默认实现类是 DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式, 它自己也有Restful的实现,具体可以参考文档的docs\actionmapper.html。
ActionProxy&ActionInvocation Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默 认实现DefaultActionProxy是由ActionInvocation持有on实例。ActionProxy作用 是如何取得Action,无论是本地还是远程。而 ActionInvocation的作用是如何执行 Action,拦截器的功能就是在ActionInvocation中实现的。
Struts2拦截器(翻译自Struts2官方网站)
Struts2拦截器(翻译自Struts2官方网站)许多的Struts2中的Action需要共享一些共用信息或者是模块,有些Action需要对输入进行验证,另外一些Action 或许需要对文件上传之前做一些逻辑处理,又或者一些Action需要对重复提交进行保护,还有一些Actiion需要在页面显示前,初始化下拉框或一些页面组件。
Struts2框架使用了Interceptor(拦截器)策略使共享这些关心的模块更简单的使用起来。
当需要使用到一些映射到Action的资源时,框架生成了Action对象,但在该Action 被执行前,执法该Action中的方法被另外一个对象拦截了,在Action执行时,可能再次被拦截,我们亲切地称此对象为拦截器。
理解拦截器拦截器能够在一个Action执行前后拦截它。
目前的很多框架的核心实现均是基于拦截器。
(本人说两句,OOP 因为拦截器而显得更为精彩,AOP必将成为下一个核心关注点)。
拦截器可以帮助实现很多公共的内容,其中有重复提交,类型转换,对象初始化,验证,文件上传,页面初始化等等。
由于每个拦截器都可以像热插拔的模块,你可以在你的Action中正确地去使用需要的拦截器。
拦截器可以配置在一个基类的action中,自定义的拦截器可以尽量少或者配合框架中的已有的拦截器。
所以套用句外国人的话说吧,在一个Action执行时,让我们为它再提升一些吧,给Action更大的舞台更强大的力量吧。
如上图所示,Struts2的Action被一个或者多个拦截器围绕,所有的用户请求都会被拦截器所拦截,最后交给Action处理,处理结果以逻辑视图的方式返回给用户,调用的流程由配置文件来实现。
在一些例子中,一个拦截器可以解决像重复提交以及验证失败这样的例子。
当然也可以改变一个Action在执行前的状态。
拦截器可以定义为一个指定执行顺序的链中,在某些情况下,拦截器的顺序非常的重要。
="struts-default">该元素的意思是定义了一个继承于struts-default包的包,那么该包中的所有action均可使用struts-default.xml中定义的拦截器以及拦截器链。
struts2拦截器详解
•
void destroy(): – 该方法在拦截器实例被销毁之前调用,用于释放在init()方法中分配的资源。该方法只执 行一次。
String intercept(ActionInvocation invocation) throws Exception: – 该方法在Action执行之前被调用,拦截器为Action提供的附加功能在该方法中实现。利用 invocation参数,可以获取action执行的状态。在intercept()方法中,如果要继续执行后续 的部分(包括余下的应用于Action的拦截器、Action和Result),可以调用invocation.invoke()。 如果要终止后续的执行,可以直接返回一个结果码,框架将根据这个结果码来呈现对应 的结果视图。
•
Struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "/dtds/struts-2.0.dtd">
•
•
说明
• • 当执行Action的input、back和cancel方法时,验证拦截器将不执行对输入数据的验证。 当执行Action的execute方法时,验证拦截器将执行对输入数据的验证。 在设置拦截器或排除的方法时,如果有多个方法,那么以逗号(,)分隔,如上所示。如果 一个方法的名字同时出现在execludeMethods和includeMethods参数中,那么它会被当 作要拦截的方法。也就是说, includeMethods优先于execludeMethods。 在编写拦截器类的时候要注意,拦截器必须是无状态的,换句话说,在拦截器类中不 应该有实例变量。这是因为struts2对每一个体Action的请求使用的是同一个拦截器实例 来拦截调用,如果拦截器有状态,在多个线程(客户端的每个请求将由服务器端的一个 线程来服务)同时访问一个拦截器实例的情况下,拦截器的状态将不可预测。
Struts2拦截器拦截器是Struts2的核心组成部分
}
二、自定义拦截器
2.通过AbstractInterceptor类实现拦截器
前面通过实现Interceptor接口实现了自定义拦截器类的,但是我 们发现就算我们不需要对拦截器的初始化和销毁进行任何操作,也不 得不实现init方法和destroy方法。
这时可以使用另外一个类AbstractInterceptor。该类是一个抽象 类并实现了Interceptor接口,其代码如下所示。 public abstract class AbstractInterceptor implements Interceptor {
3.截器配置拦截器
前面介绍了如何定义拦截器类,但是这时拦截器还不能起作用。 要拦截器其作用则必须在struts.xml文件中配置该拦截器,下面介绍 几种配置拦截器的方法。
1.最简单的配置 2.配置并传递参数 3.配置多个拦截器 4.配置拦截器栈 5.配置拦截器栈并传递参数 6.在拦截器栈中再引入拦截器栈
public void init() {//初始化方法} public void destroy() {//销毁方法} public abstract String intercept(ActionInvocation invocation) throws Exception; //拦截方法 }
二、自定义拦截器
二、自定义拦截器
4.使用拦截器
前面已经介绍了如何配置拦截器,但是现在拦截器还是不能起作 用。因为Action还不知道要使用哪个拦截器,所以还必须在Action元 素中通过添加interceptor-ref节点来指定使用哪个拦截器,代码格式 如下所示。 <action name="业务控制器名" class="业务控制器实现类">
详解Struts2拦截器机制
详解Struts2拦截器机制Struts2的核⼼在于它复杂的拦截器,⼏乎70%的⼯作都是由拦截器完成的。
⽐如我们之前⽤于将上传的⽂件对应于action实例中的三个属性的fileUpload拦截器,还有⽤于将表单页⾯的http请求参数设置成action中对应的属性的param拦截器等。
总之,在整个Struts框架中拦截器的作⽤是相当⼤的,本篇将从以下⼏点详细介绍下有关Struts拦截器的内容:拦截器在Struts中的作⽤⾃定义拦截器实现类配置拦截器(包含配置默认拦截器)引⽤拦截器配置拦截指定⽅法的拦截器拦截器的拦截顺序⼀、拦截器在Struts中的作⽤在我们的web.xml中,我们配置了⼀个过滤器,实现将所有请求交付StrutsPrepareAndExecuteFilter类。
⼀旦接受到任意action的请求,该类会创建和初始化⼀个ActionProxy实例,它代理了具体的action,在其中我们可以添加任意拦截器在execute⽅法执⾏之前和之后做⼀些额外的操作,最终会调⽤该action实例的execute⽅法,为⽤户返回视图结果字符串,然后系统会根据该视图结果字符串调取相应的视图页⾯。
下图是拦截器和action之间的关系:这是⼀种典型的AOP思想,当我们在Struts.xml中定义⼀个包的时候,⼤部分情况下我们会继承struts-default⽂件,所以虽然我们在⾃⼰的配置⽂件中并没有⼿动配置任何的拦截器,但是我们创建的action却被很多拦截器拦截处理,就是因为struts-default中配置的拦截器⽣效了。
Struts中内建了很多的拦截器,他们⼤多被配置在struts-default⽂件中,详细的内建拦截器的介绍可以参考官⽅API,接下来我们看如何⾃定义⼀个拦截器。
⼆、⾃定义拦截器实现类想要实现⾃⼰的拦截器类只需要实现 com.opensymphony.xwork2.interceptor.Interceptor.Interceptor 接⼝即可,该接⼝中有如下⼏个⽅法:public abstract void destroy();public abstract void init();public abstract String intercept(ActionInvocation paramActionInvocation)throws Exception;init ⽅法在执⾏拦截⽅法之前回调,主要⽤于初始化⼀些资源,destroy 与init ⽅法对应,在拦截器实例被销毁之前回调,主要⽤于释放在init ⽅法中打开的资源。
拦截器(Interceptor)与过滤器(Filter)
拦截器(Interceptor)与过滤器(Filter)⽬录⼀、⽤户的普通Http请求执⾏顺序⼆、过滤器、拦截器添加后的执⾏顺序三、拦截器(Interceptor)的基本定义 拦截器是⾯向切⾯(AOP)编程中应⽤的⼀种统⼀处理⽅案,就是在你的Controller、Servie或者⼀个Method调⽤⼀个Method,或者在Method调⽤⼀个Method之后,统⼀的进⾏处理的⽅案,基于Java的反射机制。
拦截器,在AOP(Aspect-Oriented Programming)中可以⽤于在某个⽅法或者字段被访问之前,进⾏拦截,然后在之前或者之后加⼊某些统⼀的处理⽅法。
拦截是AOP的⼀种具象的实现⽅式。
拦截器将很多service或者Controller中共有的⾏为提炼出来,在某些⽅法执⾏的前后执⾏,提炼为通⽤的处理⽅式,让被拦截的⽅法都能享受这⼀共有的功能,让代码更加简洁,同时,当共有的功能需要发⽣调整、变动的时候,不必修改很多的类或者⽅法,只要修改这个拦截器就可以了,可复⽤性很强。
Spring MVC 中的Interceptor拦截请求是通过HandlerInterceptor来实现的。
四、拦截器(Interceptor)必须实现的三个⽅法 1)总览 2)preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)⽅法 该⽅法将在请求处理之前进⾏调⽤。
SpringMVC 中的Interceptor 是链式的调⽤的,在⼀个应⽤中或者说是在⼀个请求中可以同时存在多个Interceptor 。
每个Interceptor 的调⽤会依据它的声明顺序依次执⾏,⽽且最先执⾏的都是Interceptor 中的preHandle ⽅法,所以可以在这个⽅法中进⾏⼀些前置初始化操作或者是对当前请求的⼀个预处理,也可以在这个⽅法中进⾏⼀些判断来决定请求是否要继续进⾏下去。
Struts 2拦截器的研究与应用
Struts 2拦截器的研究与应用拦截器是一个一组过滤器的容器,每个过滤器可以在请求到达Action之前或之后,对请求进行一些处理。
每个拦截器可以有一个或多个配置参数,用于对拦截到的请求进行一些处理,比如对请求进行过滤,对请求参数进行解密等。
Struts2内置了一系列常用的拦截器,如TokenInterceptor、PrepareInterceptor、ModelDrivenInterceptor等,我们可以直接使用。
同时,我们也可以在项目中自定义拦截器,以满足我们的特定需求。
Struts2框架中,我们可以在多个地方使用拦截器,包括全局配置、action配置以及每个interceptor的参数配置。
2、Action配置:在Action的定义中,指定一个或多个使用的拦截器。
<action name="login" class="com.test.acton.LoginAction"><interceptor-ref name="validation"><param name="excludeMethods">input,back,cancel,browse</param></interceptor-ref><result name="success">/login.jsp</result></action>3、Interceptor参数配置:在自定义拦截器中,可以自定义一些参数,用于处理某些特定的请求,在配置文件中进行配置。
Struts2的拦截器可以组成一个独立的拦截器栈,每个拦截器的执行顺序是固定的,首先执行的是拦截器栈底部的拦截器,然后执行拦截器栈中间的拦截器,最后执行拦截器栈顶的拦截器。
即:先进后出(FILO)。
Struts2_拦截器详细配置过程
Struts2 拦截器详细配置过程1:所有拦截器的超级接口Interceptor ,Action去实现这个接口; Interceptor 它其中有三个方法(init(),destroy() ,interceptor()):Init()方法:在服务器起动的时候加载一次,并且只加载一次;Destroy()方法:当拦截器销毁时执行的方法;Interceptor()方法:其中里边有一个参数invocationpublic String intercept(ActionInvocationinvocation) throws xception {System.out.println("interceptor!!");String result=invocation.invoke();return result;}Invocation.invoke()是如果只有一个拦截器执行完这个方法后,会返回给视图,如果有多个拦截器,它顺序的执行完所有的拦截器,才返回给视图.2:可以在系统初始化中给拦截器指定默认的参数(也包括了定义拦截器方式)如下:在拦截器类中把hello当做属性set/get方式注入到拦截器类中;<interceptors><!-- 先定义拦截器 --><interceptor name="myInterceptor" class="com.zzz.struts2.i nterceptor.MyInterceptor"><!-- 指定系统初始化给拦截器的参数 --><param name="hello">张钊钊</param></interceptor><!-- 加到自己设置的拦截器栈里边去 --><interceptor-stack name="myStack"><interceptor-ref name="myInterceptor"></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref></interceptor-stack></interceptors><!-- 改变系统默认的拦截器,改成自己的默认拦截器,并且一个系统只能有一个默认的拦截器,这样这个拦截器栈会默认应用到所有的Action上去 --><default-interceptor-ref name="myStack"></default-interceptor-ref>也可以在使用拦截器的时候给它设置参数:就是在一个action 的reslut下面配置上如下:<action name="register"class="com.zzz.struts2.action.RegisterAction"><result name="success">/success.jsp</result><!-- result 它其中还有一个信息转发类型 type=""记住,如果不转向JSP,转向图表,可以改变type=""值 --><result name="input">/register.jsp</result><interceptor-ref name="myInterceptor"><param name="hello">welcome</param></interceptor-ref><interceptor-ref name="myStack"></interceptor-ref></action>2.拦截器,拦截器栈和默认的拦截器之间的关系1:拦截器和拦截器栈是一个级别的,也就是说一个拦截器栈中包括许多拦截器, 一个拦截器栈中还可以包括许多拦截器栈,配置如下方式: <interceptors><!-- 先定义拦截器 --><interceptor name="myInterceptor" class="com.zzz.struts2.i nterceptor.MyInterceptor"><!-- 指定系统初始化给拦截器的参数 --><param name="hello">张钊钊</param></interceptor><!-- 加到自己设置的拦截器栈里边去 --><interceptor-stack name="myStack"><interceptor-ref name="myInterceptor"></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack></interceptors>拦截器的使用:1.先定义;2.在引用使用;<interceptor name="myInterceptor" class="com.zzz.struts2.interceptor. MyInterceptor"><interceptor-ref name="myInterceptor"></interceptor-ref>2:struts2中有一个系统默认的拦截器栈是 defaultStack,如果你手动引用自己的拦截器,系统默认的拦截器栈将不起作用;这样必需手动引入系统的拦截器栈<interceptor-ref name="defaultStack"></interceptor-ref>如果想改变系统默认的拦截器栈,可以这样配置:<default-interceptor-ref name="myStack"></default-interceptor-ref>其中myStack是自己定义的拦截器栈名字;如果拦截器栈中有多个拦截器,在执行action之前的顺序跟配置拦截器的顺序一致,而在action之后执行的顺序是相反的;3:抽象的拦截器类AbstractInterceptor1:Interceptor这个超级拦截器接口,有三方法需要实现,但是如果不想使用init();和destroy()方法,可以去继承这个抽象拦截器类;它的使用跟上边的没有什么区别;4:方法过滤拦截器MethodFilterInterceptor1:上边的拦截器都要是针对整个action的,如果针对某个方法进行拦截可以去继承这个类;它的使用跟上边的使用方法差不多,只是需要要配置它对那个方法进行拦截,方法过滤拦截器最好不要配置到自己设置默认的拦截器栈里边,自己手动配置.<interceptor-ref name="myInterceptor3"><param name="includeMethods">execute</param><param name="excludeMethods">execute</param></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref>其中includeMethods ,excludeMethods是固定写法: includeMethods 包含拦截那些方法,多个方法需要用”,”隔开; excludeMehtods是排除拦截的那些方法;5:鉴听器PreResultListener接口1:它的鉴听点在拦截器执行完某个action方法后,在渲染视图之前做一些事情;让某个类去实现这个接口;然后向需要它的拦截器中注册进去如下代码:publicclass MyInterceptor3 extends MethodFilterInterceptor { privatestaticfinallong serialVersionUID = 3756655410194005443L;@Overrideprotected StringdoIntercept(ActionInvocation invocation) throws Exception { //把鉴听器注册到拦截中去;invocation.addPreResultListener(new MyListener());System.out.println("my Interceptor3");String result=arg0.invoke();System.out.println("my interceptor3 finshed!");return result;}}。
Struts2源码分析之ParametersInterceptor拦截器
Struts2源码分析之ParametersInterceptor拦截器前⾔ParametersInterceptor拦截器其主要功能是把ActionContext中的请求参数设置到ValueStack中,如果栈顶是当前Action则把请求参数设置到了Action中,如果栈顶是⼀个model(Action实现了ModelDriven接⼝)则把参数设置到了model中。
下⾯是该拦截器的doIntercept⽅法源码:@Overridepublic String doIntercept(ActionInvocation invocation) throws Exception {Object action = invocation.getAction();//获取当前执⾏的Action对象if (!(action instanceof NoParameters)) {//判断Action是否实现了NoParameters接⼝,实现该接⼝表⽰该Action没有任何请求参数ActionContext ac = invocation.getInvocationContext();//获取ActionContext对象final Map<String, Object> parameters = retrieveParameters(ac);//获取请求参数Map//省略...if (parameters != null) {//如果请求参数不为nullMap<String, Object> contextMap = ac.getContextMap();//获取ActionContext内部的context Map,即OgnlContext对象try {//省略...ValueStack stack = ac.getValueStack();//获取值栈setParameters(action, stack, parameters);//为值栈设置参数} finally {//省略...}}}return invocation.invoke();//调⽤下⼀个拦截器}setParameters⽅法才是该拦截器的主要逻辑,现在进⼊该⽅法:protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) {ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)(ParameterNameAware) action : null;//判断Action有⽆实现ParameterNameAware接⼝Map<String, Object> params;Map<String, Object> acceptableParameters;//合法参数集合//判断参数设置是否有序,ordered默认为false,即⽆序if (ordered) {params = new TreeMap<String, Object>(getOrderedComparator());//如果有序则要获取⽐较器acceptableParameters = new TreeMap<String, Object>(getOrderedComparator());params.putAll(parameters);} else {params = new TreeMap<String, Object>(parameters);acceptableParameters = new TreeMap<String, Object>();}//迭代请求参数for (Map.Entry<String, Object> entry : params.entrySet()) {String name = entry.getKey();//判断参数是否合法,如果Action实现了ParameterNameAware则acceptableName(name)返回true且parameterNameAware.acceptableParameterName(name) //也返回true该参数才是合法的;如果Action没有实现ParameterNameAware则参数是否合法由acceptableName(name)⽅法决定boolean acceptableName = acceptableName(name) && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name));//如果参数合法if (acceptableName) {acceptableParameters.put(name, entry.getValue());//把合法参数添加到合法参数集合中}}ValueStack newStack = valueStackFactory.createValueStack(stack);//省略...for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {//迭代合法参数String name = entry.getKey();//参数名Object value = entry.getValue();//参数值try {newStack.setValue(name, value);//将该参数设置到ValueStack中} catch (RuntimeException e) {//省略...}}//省略...//看该⽅法的名称是将合法参数添加到ActionContext中,但在该拦截器中,该⽅法为空实现,⽆任何代码//该⽅法被声明为protected,即⼦类可以覆盖该⽅法以改变⾏为addParametersToContext(ActionContext.getContext(), acceptableParameters);}根据上⾯的注释⼤家应该可以发现该setParameters⽅法逻辑还是很明确的,就是先判断提交过来的参数是否合法,因为提交过来的参数会影响到值栈所以struts2要对提交过来的参数进⾏合法性检查,以防⽌恶意⽤户的攻击,凡是请求参数中表达式中含有等号(=),逗号(,),#号(#)的都是⾮法表达式,现在就去看⼀下具体是如何判断⼀个参数是否合法的。
Struts2的拦截器
exception
提供处理异常功能,将异常映射为结果
fileUpload
负责文件上传
I18n
把指定 Locale 信息放入 Session
logger
输出 Action 名称
store
存储或者访问实现 ValidationAware 接口的 Action 类出现的消息、错
误、字段错误等
model-driven
FilterDispatcher
日志拦截器
Action
Result 图 2-2 添加拦截器
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根保通据护过生高管产中线工资敷艺料设高试技中卷术资配0料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高高与中中带资资负料料荷试试下卷卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并中3试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
拦截器Interceptor的使用笔记
拦截器Interceptor的使⽤笔记参考资料参考视频:⽬的在Controller之前实现遍历Cookie值,得到token,通过token查询user对象Cookie[] cookies = request.getCookies();/*检查浏览器中有没有我们设置的cookie对象*/if(cookies != null && cookies.length != 0){for(Cookie cookie : cookies){if( "token".equals(cookie.getName())){/*根据 cookie 中我们设置的数据来查找数据库中的⽤户信息*/String token = cookie.getValue();User user = userMapper.findToken(token);if(user != null){/*根据 cookie找到了⽤户信息,把它保存到session域中*/request.getSession().setAttribute("user", user);}break;}}}代码@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {@Autowiredprivate SessionInterceptor sessionInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {/*添加拦截路径*/registry.addInterceptor(sessionInterceptor).addPathPatterns("/**");}}@Componentpublic class SessionInterceptor implements HandlerInterceptor {@AutowiredUserMapper userMapper;/**https:///hy928302776/articles/6956747.html* preHandle⽅法是进⾏处理器拦截⽤的,顾名思义,该⽅法将在Controller处理之前进⾏调⽤,SpringMVC中的Interceptor拦截器是链式的,可以同时存在* 多个Interceptor,然后SpringMVC会根据声明的前后顺序⼀个接⼀个的执⾏,⽽且所有的Interceptor中的preHandle⽅法都会在* Controller⽅法调⽤之前调⽤。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Struts 2.0系列之七Struts 2的基石——拦截器(Interceptor)首先,要跟大家道个歉,前一阵子为给客户个一个DEMO,忙得不可开交,所以很久没有更新Blog。
提到这个DEMO我想顺便跟大家分享一下心得——如果大家希望快速开发,一个类似Struts 2这样的简单方便的WEB框架必不可少。
我们在开发DEMO使用的还是Struts 1.2.8,而且没有不使用任何EL(表达式语言),导致页面出现无数类似“<%= ((Integer) request.getAttribute("xx")).intValue()%6 %>”的代码。
Struts 1.x的Form Bean的麻烦使得有部分同事直接使用request.getParam eter(String arg),继而引入另一种麻烦。
诸如此类的问题,在DEMO这样时间紧迫的项目凸显了Struts 1.x对快速开发的无能为力。
不过没办法,由于我们项目中的几个资深员工除了Struts 1.x外,对其它的WEB框架似乎不大感兴趣。
言归正传,Interceptor(以下译为拦截器)是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。
什么是拦截器拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。
它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。
同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。
拦截器链就是将拦截器按一定的顺序联结成一条链。
在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
实现原理Struts 2的拦截器实现相对简单。
当请求到达Struts 2的Servlet Dispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器,如图1所示。
图1拦截器调用序列图已有的拦截器Struts 2已经为您提供丰富多样的,功能齐全的拦截器实现。
大家可以到struts2-all-2.0.1.jar 或struts2-core-2.0.1.jar包的struts-default.xml查看关于默认的拦截器与拦截器链的配置。
在本文使用是Struts 2的最新发布版本2.0.1。
需要下载的朋友请点击以下链接:以下部分就是从struts-default.xml文件摘取的内容:sInterceptor"/><interceptor nam e="autowiring"class="com.opensymphony.xwork2.spring.in terceptor.ActionAutowiringInterceptor"/><interceptor nam e="chain"class="com.opensymphony.xwork2.interceptor.Ch ainingInterceptor"/><interceptor nam e="conversionError"class="org.apache.struts2.interceptor.S trutsConversionErrorInterceptor"/><interceptor nam e="createSession"class="org.apache.struts2.interceptor.Cre ateSessionInterceptor"/><interceptor nam e="debugging"class="org.apache.struts2.interceptor.debug ging.DebuggingInterceptor"/><interceptor nam e="external-ref"class="com.opensymphony.xwork2.interce ptor.ExternalReferencesInterceptor"/><interceptor nam e="execAndWait"class="org.apache.struts2.interceptor.Exe cuteAndWaitInterceptor"/><interceptor nam e="exception"class="com.opensymphony.xwork2.intercepto r.ExceptionMappingInterceptor"/><interceptor nam e="fileUpload"class="org.apache.struts2.interceptor.FileUpl oadInterceptor"/><interceptor nam e="i18n"class="com.opensymphony.xwork2.interceptor.I18 nInterceptor"/><interceptor nam e="logger"class="com.opensymphony.xwork2.interceptor.L oggingInterceptor"/><interceptor nam e="model-driven"class="com.opensymphony.xwork2.interc eptor.ModelDrivenInterceptor"/><interceptor nam e="scoped-m odel-driven"class="com.opensymphony.xwork 2.interceptor.ScopedModelDrivenInterceptor"/><interceptor nam e="params"class="com.opensymphony.xwork2.interceptor. ParametersInterceptor"/>PrepareInterceptor"/><interceptor nam e="static-param s"class="com.opensymphony.xwork2.interc eptor.StaticParam etersInterceptor"/><interceptor nam e="scope"class="org.apache.struts2.interceptor.ScopeInter ceptor"/><interceptor nam e="servlet-config"class="org.apache.struts2.interceptor.Ser vletConfigInterceptor"/><interceptor nam e="sessionAutowiring"class="org.apache.struts2.spring.inte rceptor.SessionContextAutowiringInterceptor"/><interceptor nam e="t im er"class="com.opensymphony.xwork2.interceptor.Ti merInterceptor"/><interceptor nam e="token"class="org.apache.struts2.interceptor.TokenInter ceptor"/><interceptor nam e="token-session"class="org.apache.struts2.interceptor.Tok enSessionStoreInterceptor"/><interceptor nam e="validation"class="com.opensymphony.xwork2.validator. ValidationInterceptor"/><interceptor nam e="workflow"class="com.opensymphony.xwork2.intercepto r.DefaultWorkflowInterceptor"/><interceptor nam e="store"class="org.apache.struts2.interceptor.MessageSto reInterceptor"/><interceptor nam e="checkbox"class="org.apache.struts2.interceptor.Checkb oxInterceptor"/><interceptor nam e="profiling"class="org.apache.struts2.interceptor.Profiling ActivationInterceptor"/>配置和使用拦截器在struts-default.xml中已经配置了以上的拦截器。