`

《研磨struts2》第十二章 CRUD综合运用 之 12.6 加入拦截器

 
阅读更多

12.6  加入拦截器

12.6.1  回顾拦截器

拦截器是Struts2的核心概念,可以在Action运行之前或Result运行之后执行一些共通的任务。

虽然学过了,但是还从来没有使用过,接下来,我们就来为这个示例添加一个自定义的拦截器,实现如下的功能:可以打印出所调用的Action,调用Action的哪个方法,所有的request参数,以及最后要跳转到哪个页面。这样有利于调试,不需要对Action或JSP的代码有任何变化,就可以在控制台里清楚的看到整个提交的细节。

       还是首先回忆一下拦截器的相关知识:

  • 编写自定义拦截器要实现Interceptor接口,在其中的intercept方法里,调用了invocation.invoke()方法则继续向内层调用。可以在invocation.invoke()方法之前或者之后做一些事情。
  • 拦截器的声明和拦截器栈的组织引用。
  • Action引用拦截器有两种方式:

l         <action>元素可以指定<interceptor-ref>子元素,这意味着这个Action自己声明了引用哪些拦截器,与其他Action无关。

l         <package>元素可以指定<default-interceptor-ref>子元素,这意味着这个包内的所有Action都要引用这些拦截器。当然,这个包内的Action可以通过为自己的<action>元素指定<interceptor-ref>子元素,来覆盖包中的定义。

  • Action引用了哪些拦截其的查找顺序:

l         先看自己的<action>元素有没有<interceptor-ref>子元素。

l         再看自己所在的<package>元素有没有<default-interceptor-ref>子元素。

l         还要看父包的<package>元素有没有<default-interceptor-ref>子元素。而且,这个过程是递归的,父包看完还要看祖包,等等。

回顾了基础知识后,就来看看,我们要为示例加入拦截器的功能,究竟要做些什么事情:

  • 实现一个自定义拦截器的类

l         在Action运行之前打印到底调用哪个Action。

l         在Action运行之前打印调用这个Action的哪个方法。

l         在Action运行之前打印request中的所有参数。

l         在Result运行之后打印到底跳转到哪个Result。

  • 在struts.xml中定义这个拦截器
  • 在struts.xml中定义一个拦截器栈,包括自定义拦截器和默认引用的defaultStack。
  • 由于这个包内的所有Action都要引用自定义拦截器,所以在这个包的<package>元素下添加<default-interceptor-ref>子元素来引用刚刚定义的拦截器栈。

12.6.2  编写自定义拦截器

看到上面描述的自定义拦截器要完成的功能,估计很多朋友都会说,实现这些功能的拦截器在6.4.1里面已经实现过了,没错,这里就是直接使用前面讲述过的那个拦截器。

为了大家阅读起来方便,还是把代码在这里示例一下,就不过多去讲述了。示例代码如下:

 

java代码:
  1. public class LoggerInterceptor implements Interceptor{    
  2.     public void destroy() { }     
  3.     public void init() {    }     
  4.     public String intercept(ActionInvocation invocation) throws Exception {  
  5.         System.out.println("-------------------------------");  
  6.         //找到运行的Action对象,并打印其类名  
  7.         System.out.println("Action:"+invocation.getAction().getClass().getName());  
  8.         //找到运行的ActionProxy对象,并打印其要运行的方法名  
  9.         System.out.println("Method:"+invocation.getProxy().getMethod());  
  10.         //找到这次请求的request中的parameter参数,并打印  
  11.         Map<String, Object> params = invocation.getInvocationContext().getParameters();  
  12.         for (String key:params.keySet()){  
  13.             Object obj = params.get(key);  
  14.               
  15.             if(obj instanceof String[]){  
  16.                 String[] arr = (String[]) obj;  
  17.                 System.out.println("Param:"+key);  
  18.                 for (String value:arr){  
  19.                     System.out.println(value);  
  20.                 }  
  21.             }  
  22.         }  
  23.           
  24.         //运行拦截器所包含的内容  
  25.         String resultCode = invocation.invoke();  
  26.         //在Action和Result运行之后,得到Result对象  
  27.         //并在可以强制转换成ServletDispatcherResult时,打印其下一个JSP的位置  
  28.         Result rresult = invocation.getResult();  
  29.         if (rresult instanceof ServletDispatcherResult){  
  30.             ServletDispatcherResult result = (ServletDispatcherResult) rresult;  
  31.             System.out.println("JSP:"+result.getLastFinalLocation());  
  32.         }  
  33.         System.out.println("-------------------------------");  
  34.         return resultCode;  
  35.     }  
  36. }  

如果有什么不太清楚的,可以回去看看,这里就不赘述了。

12.6.3  配置自定义拦截器

在配置自定义拦截器中,需要做以下的事情:

  • 定义这个自定义拦截器。
  • 定义一个拦截器栈,包括自定义拦截器和默认引用的defaultStack。
  • 由于这个包内的所有Action都要引用自定义拦截器,所以在这个包的<package>元素下添加<default-interceptor-ref>子元素来引用刚刚定义的拦截器栈。

因此,struts.xml中的<package>元素要变成如下配置:

 

java代码:
  1. <package name="crud1" namespace="/crud1" extends="struts-default">  
  2.     <interceptors>  
  3.         <!-- 定义这个自定义拦截器-->  
  4.         <interceptor name="mylogger"  
  5.             class="cn.javass.framework.web.interceptor.LoggerInterceptor"/>  
  6.         <!-- 定义一个拦截器栈,包括自定义拦截器和默认引用的defaultStack -->  
  7.         <interceptor-stack name="myStack">  
  8.             <interceptor-ref name="mylogger"/>  
  9.             <interceptor-ref name="defaultStack"/>  
  10.         </interceptor-stack>  
  11.     </interceptors>  
  12.     <!-- 为包添加默认拦截器引用,引用刚刚建立的拦截器栈 -->  
  13.     <default-interceptor-ref name="myStack"/>  
  14.       
  15.     <action name="userToList" class="cn.javass.crud1.action.UserAction" method="toList">  
  16.         <result name="toList">/jsp/list.jsp</result>  
  17.     </action>  
  18.     <action name="userToAdd" class="cn.javass.crud1.action.UserAction" method="toAdd">  
  19.         <result name="toAdd">/jsp/add.jsp</result>  
  20.     </action>  
  21.     <!-- 其他action -->  
  22. </package>  

12.6.4  使用自定义拦截器的效果

在运行之前,先来思考几个小问题:

  • UserAction改变了吗?
  • 各个JSP改变了吗?
  • struts.xml中<action>元素的配置改变了吗?

当然,答案是都没有改变。所以,加上和去掉这个拦截器,对程序的主体代码不产生影响。

       以添加页面提交为例,提交后,控制台打印出:

 

java代码:
  1. -------------------------------  
  2. Action:cn.javass.crud1.action.UserAction  
  3. Method:add  
  4. Param:user.sex  
  5. 男  
  6. Param:user.userId  
  7. 1  
  8. Param:user.name  
  9. 张三  
  10. Param:user.age  
  11. 20  
  12. JSP:/jsp/list.jsp  
  13. -------------------------------  

这样,由哪个Action响应,调用哪个方法,request中的所有参数,最后跳转到哪个JSP完全一目了然,如果出错了,不需要一点一点去打印、测试,直接在控制台就能看到绝大多数细节。

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4114.html

欢迎访问http://sishuok.com获取更多内容

2
3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics