拦截器工作流程
页面àXMl配置文件类à拦截器àLoginAction方法
配置一个自定義拦截器
struts.xml中
先声明拦截器<action内调用拦截器
定义拦截器的类
自定拦截器后需要重新调用默认拦截器,否者INPUT不在起作用
- 拦截器,是AOP(面向切面编程)编程思想
staticParam,Params,ModelDriven
Struts2执行的流程图:
拦截器的执行:
在动作类执行之间调用拦截器,顺序1,2,3
在结果视图之后还需要调用拦截器,顺序3,2,1
编写自定义拦截器
public class DemoInterceptor1 extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub
System.out.println("DemoInterceptor1,在动作类执行之前执行"); //执行Action,返回值为动作方法的返回值 //有放行的功能,如果有下一个拦截器,执行下一个,如果没有了,执行动作方法 String result = invocation.invoke(); System.out.println("DemoInterceptor1,在结果视图之后执行"); return result; } } |
<package name="p" extends="struts-default"> <!-- 先声明拦截器 --> <interceptors> <interceptor name="interceptor1" class="com.qf.web.interceptor.DemoInterceptor1"></interceptor> <interceptor name="interceptor2" class="com.qf.web.interceptor.DemoInterceptor2"></interceptor> </interceptors> <action name="demo1" class="com.qf.web.action.DemoAction1">
<!-- 使用拦截器,当配置了任意的一个拦截器,默认的拦截器栈不起作用 当配置多个拦截器时,按照配置的顺序执行 --> <interceptor-ref name="interceptor1"></interceptor-ref> <interceptor-ref name="interceptor2"></interceptor-ref>
<result name="success">/success.jsp</result> </action> </package> |
DemoInterceptor1,在动作类执行之前执行 DemoInterceptor2,在动作类执行之前执行 DemoAction Success.jsp DemoInterceptor2,在结果视图之后执行 DemoInterceptor1,在结果视图之后执行 |
- 拦截器案例
检查登录的拦截器
登录页面,用户名密码,登录
<form action="login.action" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="登录"> </form> |
用户的动作类,登录成功之后将用户信息保存到Session中
public class LoginAction extends ActionSupport { @Override public String execute() throws Exception { //将用户信息保存到Session中 HttpSession session = ServletActionContext.getRequest().getSession(); session.setAttribute("user", "user"); return SUCCESS; } } |
Login
Home:主页,登录成功之后才能访问
在访问主页时,使用拦截器检查Sesison中是否保存用户信息
//在访问主页时,使用拦截器检查Sesison中是否保存用户信息 public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // 获得Session中保存的数据 HttpSession session = ServletActionContext.getRequest().getSession(); Object user = session.getAttribute("user");
//断user是否为空,判断是否登录 if(user == null){ //表示未登录,跳转到登录页面 return "input"; }
//登录成功,放行 String result = invocation.invoke(); return result; } } |
Struts。Xml的配置
A:
<!-- a:配置自定义拦截器,检查是否登录 --> <package name="p2" extends="struts-default">
<!-- 拦截器声明 --> <interceptors> <interceptor name="loginInterceptor" class="com.qf.web.interceptor.LoginInterceptor"></interceptor> </interceptors>
<!-- 使用全局结果视图 --> <global-results> <result name="input" type="redirect">/login.jsp</result> </global-results>
<!-- 登录操作,不需要拦截 --> <action name="login" class="com.qf.web.action.LoginAction"> <result name="success">/success.jsp</result> </action> <!-- 访问主页,需要拦截检查是否登录 --> <action name="home" class="com.qf.web.action.LoginAction" method="home"> <interceptor-ref name="loginInterceptor"></interceptor-ref> <result name="success">/home.jsp</result> </action> <action name="other" class="com.qf.web.action.LoginAction" method="other"> <interceptor-ref name="loginInterceptor"></interceptor-ref> <result name="success">/home.jsp</result> </action> </package> |
B:
<!-- b:a中的问题,在action中使用拦截器,默认的拦截器栈不起作用 让默认的拦截器栈与自动以拦截器都起作用 需要自定义拦截器栈 --> <package name="p2" extends="struts-default">
<!-- 拦截器声明 --> <interceptors> <interceptor name="loginInterceptor" class="com.qf.web.interceptor.LoginInterceptor"></interceptor>
<!-- 声明拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="loginInterceptor"></interceptor-ref> </interceptor-stack> </interceptors>
<!-- 使用全局结果视图 --> <global-results> <result name="input" type="redirect">/login.jsp</result> </global-results>
<!-- 登录操作,不需要拦截 --> <action name="login" class="com.qf.web.action.LoginAction"> <result name="success">/success.jsp</result> </action> <!-- 访问主页,需要拦截检查是否登录 --> <action name="home" class="com.qf.web.action.LoginAction" method="home"> <interceptor-ref name="myStack"></interceptor-ref> <result name="success">/home.jsp</result> </action> <action name="other" class="com.qf.web.action.LoginAction" method="other"> <interceptor-ref name="myStack"></interceptor-ref> <result name="success">/home.jsp</result> </action> </package>
|
C:
<!-- c:b中存在的问题,如果action比较多,在每个action中都需要配置拦截器栈,代码重复 可以将自定义的 拦截器栈 配置为默认拦截器栈 --> <package name="p2" extends="struts-default">
<!-- 拦截器声明 --> <interceptors> <interceptor name="loginInterceptor" class="com.qf.web.interceptor.LoginInterceptor"></interceptor>
<!-- 声明拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="loginInterceptor"></interceptor-ref> </interceptor-stack>
</interceptors>
<!-- 配置默认拦截器栈 --> <default-interceptor-ref name="myStack"/>
<!-- 使用全局结果视图 --> <global-results> <result name="input" type="redirect">/login.jsp</result> </global-results>
<!-- 登录操作,不需要拦截 --> <action name="login" class="com.qf.web.action.LoginAction"> <result name="success">/success.jsp</result> </action> <!-- 访问主页,需要拦截检查是否登录 --> <action name="home" class="com.qf.web.action.LoginAction" method="home"> <result name="success">/home.jsp</result> </action> <action name="other" class="com.qf.web.action.LoginAction" method="other"> <result name="success">/home.jsp</result> </action> </package>
|
D:
<!-- d:c中的问题,配置了默认的拦截器栈,当登录时也被拦截 解决:登录时不被拦截,其他action被拦截 修改自定义拦截器的父类为MethodFilterInterceptor AbstractInterceptor有一个子类MethodFilterInterceptor 有两个属性,excludeMethods,includeMethods 给属性注入值,屏蔽掉某些方法 --> <package name="p2" extends="struts-default">
<!-- 拦截器声明 --> <interceptors> <interceptor name="loginInterceptor" class="com.qf.web.interceptor.LoginInterceptor"></interceptor>
<!-- 声明拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="loginInterceptor"> <!-- 给属性注入值,通知某些方法不被拦截 --> <param name="excludeMethods">execute</param> </interceptor-ref> </interceptor-stack>
</interceptors>
<!-- 配置默认拦截器栈 --> <default-interceptor-ref name="myStack"/>
<!-- 使用全局结果视图 --> <global-results> <result name="input" type="redirect">/login.jsp</result> </global-results>
<!-- 登录操作,不需要拦截 --> <action name="login" class="com.qf.web.action.LoginAction"> <result name="success">/success.jsp</result> </action> <!-- 访问主页,需要拦截检查是否登录 --> <action name="home" class="com.qf.web.action.LoginAction" method="home"> <result name="success">/home.jsp</result> </action> <action name="other" class="com.qf.web.action.LoginAction" method="other"> <result name="success">/home.jsp</result> </action> </package> |
最终版本:
<!-- e:d中的问题,在定义拦截器栈时,还不知道哪些方法需要拦截,或不需要拦截 解决:在使用拦截器时,给属性注入值,指定拦截的方法 --> <package name="p2" extends="struts-default">
<!-- 拦截器声明 --> <interceptors> <interceptor name="loginInterceptor" class="com.qf.web.interceptor.LoginInterceptor"></interceptor>
<!-- 声明拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="loginInterceptor">
</interceptor-ref> </interceptor-stack>
</interceptors>
<!-- 配置默认拦截器栈 --> <default-interceptor-ref name="myStack"/>
<!-- 使用全局结果视图 --> <global-results> <result name="input" type="redirect">/login.jsp</result> </global-results>
<!-- 登录操作,不需要拦截 --> <action name="login" class="com.qf.web.action.LoginAction">
<!-- 给拦截器注入不被拦截的方法 此时param使用在默认拦截器栈中,对应多个拦截器,需要明确指定给某个拦截器的属性注入值 拦截器名称.属性名称 --> <interceptor-ref name="myStack"> <param name="loginInterceptor.excludeMethods">execute</param> </interceptor-ref> <result name="success">/success.jsp</result> </action> <!-- 访问主页,需要拦截检查是否登录 --> <action name="home" class="com.qf.web.action.LoginAction" method="home"> <result name="success">/home.jsp</result> </action> <action name="other" class="com.qf.web.action.LoginAction" method="other"> <result name="success">/home.jsp</result> </action> </package> |