隨筆 - 117  文章 - 72  trackbacks - 0

          聲明:原創作品(標有[原]字樣)轉載時請注明出處,謝謝。

          常用鏈接

          常用設置
          常用軟件
          常用命令
           

          訂閱

          訂閱

          留言簿(7)

          隨筆分類(130)

          隨筆檔案(123)

          搜索

          •  

          積分與排名

          • 積分 - 155795
          • 排名 - 390

          最新評論

          [標題]:[原]Struts2-攔截器
          [時間]:2009-7-31
          [摘要]:Struts Interceptor
          [關鍵字]:浪曦視頻,Struts2應用開發系列,WebWork,Apache,Interceptor,攔截器,動態代理,Java,Proxy
          [環境]:struts-2.1.6、JDK6、MyEclipse7、Tomcat6
          [作者]:Winty (wintys@gmail.com) http://www.aygfsteel.com/wintys

          [正文]:
          1、知識點
          a.Struts2攔截器Interceptor
              Struts2攔截器的根接口為: xwork-2.1.2.jar/com.opensymphony.xwork2.interceptor.Interceptor
              自定義的攔截器可以實現Interceptor接口。com.opensymphony.xwork2.interceptor.AbstractInterceptor 提供了對Interceptor的默認實現,自定義攔截器也可以繼承AbstractInterceptor。

          b.定義攔截器
          /StrutsHelloWorld/src/wintys/struts2/interceptor/MyInterceptor.java:
          package wintys.struts2.interceptor;

          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.Interceptor;

          /**
           * 攔截器、Interceptor
           *
           * http://www.aygfsteel.com/wintys
           * @author Winty (wintys@gmail.com)
           * @version 2009-07-30
           *
           */
          @SuppressWarnings("serial")
          public class MyInterceptor implements Interceptor {

              @Override
              public String intercept(ActionInvocation invocation) throws Exception {
                  
                  System.out.println("before...");
                  
                  String result = invocation.invoke();
                  
                  System.out.println("after...");
                  
                  return result;
              }

              @Override
              public void destroy() {
                  System.out.println("MyInterceptor destroy()...");
              }

              @Override
              public void init() {
                  System.out.println("MyInterceptor init()...");
              }

          }

          c.在struts.xml中配置攔截器
          <package name="MyStruts" extends="struts-default">
              <interceptors>
                      <interceptor name="myInterceptor" class="wintys.struts2.interceptor.MyInterceptor" />

                      <interceptor-stack name="myStack">
                          <interceptor-ref name="myInterceptor"/>
                          <interceptor-ref name="defaultStack"/>
                      </interceptor-stack>
              </interceptors>
              ......
              <action name="intercept" class="wintys.struts2.interceptor.InterceptAction">
                  <result name="success">/interceptor/output.jsp</result>
                     <result name="input">/interceptor/input.jsp</result>
                  <interceptor-ref name="myStack" />
              </action>
          </package>

              defaultStack是Struts默認的攔截器。在action中手動引入interceptor后,就不會啟用默認的interceptor,除非手動引入。所以要加上默認interceptor:<interceptor-ref name="defaultStack">。

              在input.jsp請求Action "intercept"時,在Action的execute()方法執行時,就會觸發攔截器。

          d.帶參數的攔截器
              配置(在定義時給參數賦值):
              <interceptor name="myParamInterceptor" class="wintys.struts2.interceptor.MyParamInterceptor" >
                  <param name="info">This is a param.</param>
              </interceptor>

              在自定義攔截器中實現代碼(添加info屬性、setter和getter):
          /StrutsHelloWorld/src/wintys/struts2/interceptor/MyParamInterceptor.java
          package wintys.struts2.interceptor;

          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

          /**
           * 帶參數的攔截器、AbstractInterceptor
           *
           * http://www.aygfsteel.com/wintys
           * @author Winty (wintys@gmail.com)
           * @version 2009-07-30
           *
           */
          @SuppressWarnings("serial")
          public class MyParamInterceptor extends AbstractInterceptor {
              private String info;
              
              public String getInfo() {
                  return info;
              }

              public void setInfo(String info) {
                  this.info = info;
              }

              @Override
              public String intercept(ActionInvocation invocation) throws Exception {
                  System.out.println("before2...");
                  System.out.println("info:" + info);
                  
                  String result = invocation.invoke();
                  
                  System.out.println("after2...");
                  
                  return result;
              }

          }

              在引用時給參數賦值,會覆蓋定義時的賦值:
              <interceptor-ref name="myParamInterceptor">
                  <param name="info">This is another param.</param>
              </interceptor-ref>


          e.攔截器棧
              攔截器棧與攔截器具有同等地位,使用相同。攔截器棧可以再包含攔截器或攔截器棧。
          <interceptors>
              <interceptor-stack name="myStack">
                  <interceptor-ref name="myInterceptor" />
                  <interceptor-ref name="defaultStack" />
              </interceptor>
          </interceptors>

              攔截器棧中定義的多個攔截器執行順序與攔截器配置順序相同。同時,多個攔截器的執行流程如下: interceptorA begin => interceptorB begin => action => interceptorB end => interceptorA end


          f.指定默認攔截器    
              Struts默認的攔截器是defaultStack,可以在struts.xml中使用如下配置重新指定默認攔截器:
          <package>
              ......
              <default-interceptor-ref name="myStack" />
              ......
          </package>


          g.方法過濾攔截器MethodFilterInteceptor
              MethodFilterInteceptor可以選擇需要過濾的方法,通過參數進行配置。實現MethodFilterInteceptor.doIntercept(),以提供攔截功能。
          <action>
              <interceptor-ref name="myInterceptor">
                  <param name="includeMethods">test,execute</param>
                  <param name="excludeMethods">somemethod</param>
              </interceptor-ref>
          </action>


          f.PreResultListener
              可以在攔截器中添加PreResultListener,以實現特定功能。PreResultListener在業務方法(通常為execute)返回后(執行成功則返回"success"),頁面視圖呈現到客戶端之前執行。

              public String intercept(ActionInvocation invocation) throws Exception {
                  ......
                  invocation.addPreResultListener(...);
                  ......
              }


          2、詳細代碼
          /StrutsHelloWorld/src/wintys/struts2/interceptor/MyMethodFilterInterceptor.java:
          package wintys.struts2.interceptor;

          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
          import com.opensymphony.xwork2.interceptor.PreResultListener;

          /**
           * 選擇性攔截方法的攔截器MethodFilterInterceptor、監聽器PreResultListener
           *
           * http://www.aygfsteel.com/wintys
           * @author Winty (wintys@gmail.com)
           * @version 2009-07-30
           *
           */
          @SuppressWarnings("serial")
          public class MyMethodFilterInterceptor extends MethodFilterInterceptor {

              @Override
              protected String doIntercept(ActionInvocation invocation) throws Exception {
                  System.out.println("MyMethodFilterInterceptor is running...");
                  
                  //添加監聽器PreResultListener
                  invocation.addPreResultListener(new PreResultListener(){
                      public void beforeResult(ActionInvocation invocation, String resultCode){
                          System.out.println("PreResultListener ..." + resultCode);
                      }
                      
                  });
                  
                  String result = invocation.invoke();        
                  
                  return result;
              }

          }


          /StrutsHelloWorld/WebRoot/interceptor/input.jsp:
          <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
          <%@ taglib uri="/struts-tags" prefix="s" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
            <head>
              <title></title>
            </head>
           
            <body>
            <s:form action="intercept">
                <s:textfield name="user" label="user" /><br/>
                <s:submit name="submit" label=" 提交  " />
            </s:form>
              
            </body>
          </html>



          /StrutsHelloWorld/src/wintys/struts2/interceptor/InterceptAction.java:
          package wintys.struts2.interceptor;

          import com.opensymphony.xwork2.ActionSupport;

          /**
           *
           * @author Winty (wintys@gmail.com)
           * @version 2009-07-30
           * http://www.aygfsteel.com/wintys
           */
          @SuppressWarnings("serial")
          public class InterceptAction extends ActionSupport {
              private String user;

              public String getUser() {
                  return user;
              }

              public void setUser(String user) {
                  this.user = user;
              }
              
              @Override
              public String execute() throws Exception {
                  System.out.println("execute()...");
                  
                  return SUCCESS;
              }
              
              @Override
              public void validate() {
                  System.out.println("validate()...");
                  
                  if(user == null || user.length() < 6){
                      addFieldError("user", "invalid user");
                  }
              }
          }



          /StrutsHelloWorld/WebRoot/interceptor/output.jsp:
          <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
          <%@ taglib uri="/struts-tags" prefix="s" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
            <head>
              <title>My JSP 'output.jsp' starting page</title>    
           </head>
           
            <body>
              <s:property value="user"/>
            </body>
          </html>


          /StrutsHelloWorld/src/struts.xml:
          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE struts PUBLIC
              "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
              "http://struts.apache.org/dtds/struts-2.0.dtd">

          <struts>
              <package name="MyStruts" extends="struts-default">
                  <!-- 攔截器 -->
                  <interceptors>
                      <interceptor name="myInterceptor" class="wintys.struts2.interceptor.MyInterceptor" />
                      <interceptor name="myParamInterceptor" class="wintys.struts2.interceptor.MyParamInterceptor" >
                          <param name="info">This is a param.</param>
                      </interceptor>
                      <interceptor name="myMethodFilterInterceptor" class="wintys.struts2.interceptor.MyMethodFilterInterceptor">
                          <param name="includeMethods">execute</param>
                      </interceptor>
                      
                      <interceptor-stack name="myStack">
                          <interceptor-ref name="myParamInterceptor">
                              <param name="info">This is another param.</param>
                          </interceptor-ref>
                          <interceptor-ref name="myInterceptor"/>
                          <interceptor-ref name="myMethodFilterInterceptor"/>
                          <interceptor-ref name="defaultStack"/>
                      </interceptor-stack>
                  </interceptors>
                        
                  <action name="intercept" class="wintys.struts2.interceptor.InterceptAction">
                      <result name="success">/interceptor/output.jsp</result>
                         <result name="input">/interceptor/input.jsp</result>
                         <interceptor-ref name="myStack" />
                  </action>
                  
              </package>
          </struts>

          3、小例子:登錄攔截
              登錄攔截:攔截Action實現在輸入信息之前必須登錄,如果沒有登錄,則轉到登錄頁面。

          /StrutsHelloWorld/WebRoot/interceptor/login.jsp:
          <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
          <%@ taglib uri="/struts-tags" prefix="s" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
            <head>
              <title></title>
            </head>
           
            <body>
            <s:form action="authentication">
              正確id:10000
                <s:textfield name="id" label="id" /><br/>
                <s:submit name="submit" label=" 提交  " />
            </s:form>
              
            </body>
          </html>

          Struts2中的Session可以脫離容器,以方便測試,對應于容器中的Session。

          /StrutsHelloWorld/src/wintys/struts2/interceptor/AuthenticationAction.java:
          package wintys.struts2.interceptor;

          import java.util.Map;

          import com.opensymphony.xwork2.ActionContext;
          import com.opensymphony.xwork2.ActionSupport;

          @SuppressWarnings("serial")
          public class AuthenticationAction extends ActionSupport {
              private String id;

              public String getId() {
                  return id;
              }

              public void setId(String id) {
                  this.id = id;
              }
              
              @Override
              public String execute() throws Exception {
                  
                  if( id.equals("10000")){
                      Map<String , Object> map = ActionContext.getContext().getSession();
                      map.put("id", id);
                      
                      return SUCCESS;
                  }
                  else{
                      addFieldError("id", "id error");
                      
                      return INPUT;
                  }
              }
              
              @Override
              public void validate() {
                  if(id == null || id.length() < 3)
                      addFieldError("id", "invalid id");
              }
          }


          /StrutsHelloWorld/src/wintys/struts2/interceptor/AuthenticationInterceptor.java:
          package wintys.struts2.interceptor;

          import java.util.Map;

          import com.opensymphony.xwork2.Action;
          import com.opensymphony.xwork2.ActionInvocation;
          import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

          /**
           * 認證攔截器:判斷用戶是否已登錄
           *
           * http://www.aygfsteel.com/wintys
           * @author Winty (wintys@gmail.com)
           * @version 2009-07-30
           *
           */
          @SuppressWarnings("serial")
          public class AuthenticationInterceptor extends AbstractInterceptor {

              @Override
              public String intercept(ActionInvocation invocation) throws Exception {
                  System.out.println("AuthenticationInterceptor ...");
                  
                  Map<String , Object> map = invocation.getInvocationContext().getSession();
                  
                  Object id = map.get("id");
                  if( id == null){
                      return Action.LOGIN;
                  }else{
                      System.out.println("id" + id);
                      
                      return invocation.invoke();
                  }
              }

          }


          struts.xml配置:
          ......
          <package name="MyStruts" extends="struts-default">
                  <!-- 攔截器 -->
                  <interceptors>
                      <interceptor name="authenticationInterceptor" class="wintys.struts2.interceptor.AuthenticationInterceptor"/>
                      
                      <interceptor-stack name="myStack">
                          <interceptor-ref name="authenticationInterceptor"/>
                          <interceptor-ref name="defaultStack"/>
                      </interceptor-stack>
                  </interceptors>
                  
                  <!-- 全局result -->
                  <global-results>
                      <result name="login" type="redirect">/interceptor/login.jsp</result>
                  </global-results>
                  
                  <action name="intercept" class="wintys.struts2.interceptor.InterceptAction">
                      <result name="success">/interceptor/output.jsp</result>
                         <result name="input">/interceptor/input.jsp</result>
                         <interceptor-ref name="myStack" />
                  </action>
                  <action name="authentication" class="wintys.struts2.interceptor.AuthenticationAction">
                      <result name="success">/interceptor/input.jsp</result>
                      <result name="input" type="dispatcher">/interceptor/login.jsp</result>
                  </action>
                  
          </package>
          ......

          [參考資料]:
              《浪曦視頻之Struts2應用開發系列》

          [附件]:
              源代碼: http://www.aygfsteel.com/Files/wintys/struts_HelloWorld_Interceptor.zip
          posted on 2009-08-01 00:21 天堂露珠 閱讀(760) 評論(0)  編輯  收藏 所屬分類: Struts
          主站蜘蛛池模板: 博野县| 崇文区| 兴和县| 罗田县| 安顺市| 黑河市| 理塘县| 湟源县| 宜兰县| 新邵县| 余江县| 富阳市| 岢岚县| 东城区| 咸丰县| 石家庄市| 新营市| 福安市| 贵德县| 夏邑县| 吉林省| 岱山县| 吉木萨尔县| 迭部县| 淮南市| 台江县| 阿克陶县| 洞口县| 墨玉县| 阜城县| 扎兰屯市| 漠河县| 方城县| 汕尾市| 民勤县| 双柏县| 昭觉县| 宁远县| 苏尼特右旗| 辽中县| 丽江市|