6.4 两个有用的拦截器
6.4.1 更强大的logger拦截器
在学习了这么多拦截器的理论知识过后,来示范两个真实项目中用得到的拦截器。先来看看更强大的logger拦截器。
Struts2自带的logger拦截器只是打印出了Action所对应的URL以及执行的方法名称,这对实际开发来说是肯定不够的。
实际开发中为了调试方便,要记录的信息比较多,通常需要把这次请求相关的几乎所有信息都打印出来,比如:
- 要访问哪个Action类
- 要访问这个Action类的哪个方法
- 打印出这次请求中所有的request中的parameter参数
- 这次请求最后跳转到哪个页面。
如果我们现在就要在拦截器中实现这样的功能,该怎么实现呢?
1:ActionInvocation接口
在实现拦截器的功能的时候,需要使用ActionInvocation接口,这个接口有很多的功能,这里并不打算全部讲到,只描述一下接下来我们要用到的功能,更多的功能请参见Struts2的API文档。
- getAction方法:返回这次请求准备执行的Action对象。
- getProxy方法:返回这次请求的ActionProxy对象,可以在这个对象上获得要运行Action的哪个方法。
- getInvocationContext方法:返回这个Action执行的上下文(ActionContext),可以在这个上下文对象中获取到大量的数据,比如请求的parameter值、session的值等等。
在ActionContext中取到的parameter值是一个Map<String,Object>,其中以String为key,以String[]为value。这个Map中记录了所有的request参数。
- getResult方法:返回Result运行之后代表结果的Result对象。
2:具体的LoggerInterceptor,示例代码如下:
java代码:
- package cn.javass.action.action;
-
- import java.util.Map;
- import org.apache.struts2.dispatcher.ServletDispatcherResult;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.Result;
- import com.opensymphony.xwork2.interceptor.Interceptor;
-
- public class LoggerInterceptor implements Interceptor{
- public void destroy() {
- }
- public void init() {
- }
- public String intercept(ActionInvocation invocation) throws Exception {
- System.out.println("begin-------------------------------");
-
- System.out.println("Action:"+invocation.getAction().getClass().getName());
-
- System.out.println("Method:"+invocation.getProxy().getMethod());
-
- Map<String, Object> params = invocation.getInvocationContext().getParameters();
- for (String key:params.keySet()){
- Object obj = params.get(key);
-
- if(obj instanceof String[]){
- String[] arr = (String[]) obj;
- System.out.println("Param:"+key);
- for (String value:arr){
- System.out.println(value);
- }
- }
- }
-
-
- String resultCode = invocation.invoke();
-
-
-
- Result rresult = invocation.getResult();
- if (rresult instanceof ServletDispatcherResult){
- ServletDispatcherResult result = (ServletDispatcherResult) rresult;
- System.out.println("JSP:"+result.getLastFinalLocation());
- }
-
- System.out.println("end-------------------------------"); return resultCode;
- }
- }
3:在struts.xml中配置和使用这个拦截器,示例如下:
java代码:
- <package name="helloworld" extends="struts-default">
- <interceptors>
- <interceptor name="MyLogger" class="cn.javass.action.action.LoggerInterceptor"/>
- </interceptors>
-
- <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">
- <result name="toWelcome">/s2impl/welcome.jsp</result>
- <interceptor-ref name="MyLogger"/>
- <interceptor-ref name="defaultStack"/>
- </action>
- </package>
4:测试一下,运行登录页面,填入用户名和密码,点击提交按钮。然后查看后台的输出,示例如下:
java代码:
- begin-------------------------------
- Action:cn.javass.action.action.HelloWorldAction
- Method:execute
- Param:submitFlag
- login
- Param:account
- test
- Param:password
- test
- 用户输入的参数为===account=test,password=test,submitFlag=login
- JSP:/s2impl/welcome.jsp
- end-------------------------------
上面加粗的那句话,是Action运行的时候输出的信息,其余信息就是由我们的拦截器来输出的了。
基本实现了前面提出的四个要求,分别输出了如下信息:运行哪个Action类,运行哪个方法,请求的参数,Action运行完要跳转到哪个JSP。
这些信息对我们进行调试是非常有用的。
6.4.2 登录检查拦截器
在实际开发中,一个常见的功能要求是:有很多操作都需要登录后才能操作,如果操作的时候还没有登录,那么通常情况下会要求跳转回到登录页面。
1:如何实现这样的功能呢?
在具体实现之前,先来考虑几个问题:
(1)这个功能应该在哪里实现?
要实现登录检查的功能,很明显是在Action运行之前,就要判断用户是否登陆了,判断方式是看session里面是否有相关信息,如果有,则继续操作;如果没有,则要跳转到预先制定好的登录页面。
简单点说,登录检查应该写在“invocation.invoke();”语句之前。
(2)是否需要参数?
要判断是否需要参数,其实就是判断这个拦截器有没有什么可变的量,可以把这些可变量从程序中分离出来,通过struts.xml来配置。经过分析,可以抽出两个参数:
- 代表登陆页面的Result
- 判断session中哪个attribute,也就是attribute的名称
(3)如何引用呢?
现在的情况是只有部分Action需要登陆录检查,另外一些Action不需要,这就需要权衡了。对于大多数Action都要进行登录检查的包,可以在包的默认拦截器引用上设置登录检查,而对于少数不需要登陆检查的Action,可以让它们直接引用默认的defaultStack拦截器栈。
2:接下来,就来实现满足要求的拦截器,示例代码如下:
java代码:
- package cn.javass.action.action;
- padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; bo
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。