Struts2——拦截器(Interceptor)
来源:互联网 发布:db2还原数据库指令 编辑:程序博客网 时间:2024/06/05 03:28
拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也提供了一种可以提取Action中可重用的代码的方式。
1、Struts2中内置的拦截器
常见的拦截器:
(1)params拦截器
这个拦截器把请求参数设置到相应的Action的属性去,并自动进行类型转换。
(2)modelDriven拦截器
如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中。
(3)execption拦截器
顾名思义,在抛出异常的时候,这个拦截器起作用。最好把它放在第一位,让它能捕获所有的异常。
(4)validation拦截器
调用验证框架读取 *-validation.xml文件,并且应用在这些文件中声明的校验。
(5)token拦截器
核对当前Action请求(request)的有效标识,防止重复提交Action请求。
(6)fileUpload拦截器
用来处理文件上传
(7)workflow拦截器
调用Action的validate方法,一旦有错误返回,重新定位到INPUT结果视图
(8)servletConfig
通过感知接口,获取感应对象
2、自定义拦截器
(1)步骤:
①自定义一个类,继承AbstractInterceptor抽象类,或实现Interceptor接口
②在struts.xml配置文件中注册拦截器
③在struts.xml配置文件中,设置默认拦截器或配置Action类的局部拦截器来使用。
(2)eg:该示例自定义拦截器拦截主页面,防止未登录用户强行登陆主页面。
①CheckLoginInterceptors.java(拦截器)
public class CheckLoginInterceptors extends AbstractInterceptor{private static final long serialVersionUID = 1L;@Overridepublic String intercept(ActionInvocation invocation) throws Exception {//获取Session对象中的用户信息String username = (String) ActionContext.getContext().getSession().get("USER_IN_SESSION");if(username!=null){return invocation.invoke();//如果username不为空,放行}return "input";//否则返回登录页面}}②LoginAction.java
public class LoginAction extends ActionSupport{private static final long serialVersionUID = 1L;private String username;private String password;@Overridepublic String execute() throws Exception{System.out.println(username+","+password);//将用户名存入Session对象中ActionContext.getContext().getSession().put("USER_IN_SESSION", username);return "success";}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}
③struts.xml
<package name="interPkg" extends="struts-default" namespace="/"><!-- 注册拦截器 --><interceptors><interceptor name="checkLogin" class="interceptors.CheckLoginInterceptors"/></interceptors><!-- 指定默认拦截器 --><default-interceptor-ref name="checkLogin"/><!-- 全局视图 --><global-results><result name="input">/views/login/login.jsp</result></global-results><action name="login" class="action.interceptors.LoginAction"> <result name="success" type="redirectAction"><param name="namespace">/</param><param name="actionName">main</param></result></action><action name="main"><result name="success" type="dispatcher">/views/login/welcome.jsp</result></action></package>上述代码存在问题:
a.登陆失败,永远进不了LoginAction
原因:进入LoginAction之前,需要判断session中是否有USER_IN_SESSION,而USER_IN_SESSION只有在LoginAction中才能设置。
结论:LoginAction不需要做登陆检查。
b.在LoginAction中再也获取不了请求参数
原因:当我们在<package>设置了默认的拦截器引用,那么<package>之前的默认的拦截器栈(defaultStack)就不引用了,那么defaultStack中的获取请求参数的拦截器也不再引用。
应改为如下:
<package name="interPkg" extends="struts-default" namespace="/"><!-- 注册拦截器 --><interceptors><interceptor name="checkLogin" class="interceptors.CheckLoginInterceptors"/><!-- 自定义拦截器栈,可放置多个拦截器 --><interceptor-stack name="myStack"><interceptor-ref name="checkLogin"/><interceptor-ref name="defaultStack"/></interceptor-stack></interceptors><!-- 指定默认拦截器 --><default-interceptor-ref name="myStack"/><!-- 全局视图 --><global-results><result name="input">/views/login/login.jsp</result></global-results><action name="login" class="action.interceptors.LoginAction"><!-- 配置局部拦截器 --><interceptor-ref name="defaultStack"/><result name="success" type="redirectAction"><param name="namespace">/</param><param name="actionName">main</param></result></action><action name="main"><result name="success" type="dispatcher">/views/login/welcome.jsp</result></action></package>
④测试
使用隐身窗口重新登陆,试图登陆主页