Struts2中Action詳解

          Posted on 2008-02-15 18:42 flustar 閱讀(5980) 評論(1)  編輯  收藏 所屬分類: Struts2

              在Struts2Action部分,也就是Controller層采用了低侵入的方式。為什么這么說?這是因為在Struts2action類并不需要繼承任何的基類,或實現任何的接口,更沒有與ServletAPI直接耦合。它通常更像一個普通的POJO(通常應該包含一個無參數的execute方法),而且可以在內容定義一系列的方法(無參方法),并可以通過配置的方式,把每一個方法都當作一個獨立的action來使用,從而實現代碼復用。

          例如:

          package example;

          public class UserAction {

                 private String username;

                 private String password;

              public String execute() throws Exception {

                        //…………..

                  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;

              }

          }

          在這個Action類里的屬性,既可以封裝參數,又可以封裝處理結果。系統并不會嚴格區分它們。

          但是為了使用戶開發的Action類更規范,Struts2為我們提供了一個接口Action,該類定義如下:

          publicinterface Action {

              publicstaticfinal String ERROR="error";

              publicstaticfinal String INPUT="input";

              publicstaticfinal String NONE="none";

              publicstaticfinal String LOGIN="login";

              publicstaticfinal String SUCCESS="success";

              public String execute()throws Exception;

          }

          但是我們寫Action通常不會實現該接口,而是繼承該接口的實現類ActionSupport.

          該類代碼如下:

          public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {

               ................

              public void setActionErrors(Collection errorMessages) {

                  validationAware.setActionErrors(errorMessages);

              }

              public Collection getActionErrors() {

                  return validationAware.getActionErrors();

              }

              public void setActionMessages(Collection messages) {

                  validationAware.setActionMessages(messages);

              }

              public Collection getActionMessages() {

                  return validationAware.getActionMessages();

              }

                 public Collection getErrorMessages() {

                  return getActionErrors();

              }

                 public Map getErrors() {

                  return getFieldErrors();

              }

          //設置表單域校驗錯誤

              public void setFieldErrors(Map errorMap) {

                  validationAware.setFieldErrors(errorMap);

              }

              public Map getFieldErrors() {

                  return validationAware.getFieldErrors();

              }

              public Locale getLocale() {

                  ActionContext ctx = ActionContext.getContext();

                  if (ctx != null) {

                      return ctx.getLocale();

                  } else {

                      LOG.debug("Action context not initialized");

                      return null;

                  }

              }

          //獲取國際化信息的方法

              public String getText(String aTextName) {

                  return textProvider.getText(aTextName);

              }

              public String getText(String aTextName, String defaultValue) {

                  return textProvider.getText(aTextName, defaultValue);

              }

              public String getText(String aTextName, String defaultValue, String obj) {

                  return textProvider.getText(aTextName, defaultValue, obj);

              }

                 .........

           //用于訪問國際化資源包的方法

              public ResourceBundle getTexts() {

                  return textProvider.getTexts();

              }

              public ResourceBundle getTexts(String aBundleName) {

                  return textProvider.getTexts(aBundleName);

              }

          //添加action的錯誤信息

              public void addActionError(String anErrorMessage) {

                  validationAware.addActionError(anErrorMessage);

              }

          //添加action的普通信息

              public void addActionMessage(String aMessage) {

                  validationAware.addActionMessage(aMessage);

              }

              public void addFieldError(String fieldName, String errorMessage) {

                  validationAware.addFieldError(fieldName, errorMessage);

              }

                

              public void validate() {

              }

              public Object clone() throws CloneNotSupportedException {

                  return super.clone();

              }

           ..........

          }

          前面說到struts2并沒有直接與Servlet的API耦合,那么它是怎么訪問Servlet的API的呢?

          原來struts2中提供了一個ActionContext類,該類模擬了Servlet的API。其主要方法如下:

          1)Object get (Object key):該方法模擬了HttpServletRequest.getAttribute(String name)方法。

          2)Map getApplication()返回一個Map對象,該對象模擬了ServletContext實例.

          3)static ActionContext getContext():獲取系統的ActionContext實例。

          4)Map getSession():返回一個Map對象,該對象模擬了HttpSession實例.

          5)Map getParameters():獲取所有的請求參數,模擬了HttpServletRequest.getParameterMap()

          你也許會奇怪為什么這些方法老是返回一個Map?這主要是為了便于測試。至于它是怎么把Map對象與實際的Servlet API的實例進行轉換的,這個我們根本就不要擔心,因為struts2已經內置了一些攔截器來幫我們完成這一轉換。

          為了直接使用Servlet的API,Struts2為我們提供了以下幾個接口。

          1)ServletContextAware:實現該接口的Action可以直接訪問ServletContext實例。

          2)ServletRequestAware:實現該接口的Action可以直接訪問HttpServletRequest實例。

          3)ServletResponseAware:實現該接口的Action可以直接訪問HttpServletResponse實例。

          以上主要講了action訪問servlet,下面讓我們來看一下Struts2的Action是如何實現代碼復用的。就拿UserAction來說,我如果讓這個action既處理用戶注冊(regist)又處理登錄(longin)該如何改寫這個action呢?改寫后的UserAction如下:

          package example;

          public class UserAction extends ActionSupport {

                 private String username;

                 private String password;

              public String regist() throws Exception {

                        //…………..

                  return SUCCESS;

              }

           public String login() throws Exception {

                        //…………..

                  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;

              }

          }

          是不是這么寫就ok了,當然不行我們還必須在struts.xml文件中配置一下。配置方法有兩種:

          1)      使用普通的方式為Action元素指定method屬性.

          <action name=”loginAction” class=”example.UserAction” method=”login”>

                 <result name=”success”>/success.jsp</result>

          </action>

          <action name=”registAction” class=”example.UserAction” method=”regist”>

                 <result name=”success”>/success.jsp</result>

          </action>

          2)      采用通配符的方式為Action元素指定method屬性。

          <action name=”*Action” class=”example.UserAction” method=”{1}”>

                 <result name=”success”>/success.jsp</result>

          </action>

          使用通配符的方式過于靈活,下面是一個較復雜的配置情況。

          <action name=”*_*” class=”example.{1}Action” method=”{2}”>

          ……….

           </action>

          其中占位符{1}_的前一個*匹配,{2}與后一個*匹配。

          Feedback

          # re: Struts2中Action詳解[未登錄]  回復  更多評論   

          2013-03-05 04:33 by oo
          oo

          posts - 146, comments - 143, trackbacks - 0, articles - 0

          Copyright © flustar

          主站蜘蛛池模板: 威宁| 鲜城| 桦南县| 南皮县| 肇州县| 平远县| 资溪县| 故城县| 宁陕县| 平利县| 永泰县| 调兵山市| 台南市| 通江县| 永和县| 陆河县| 泗阳县| 定结县| 关岭| 松溪县| 娱乐| 高阳县| 苏尼特右旗| 体育| 阜新市| 开原市| 永定县| 临澧县| 太白县| 名山县| 麦盖提县| 桃园市| 肃南| 类乌齐县| 麟游县| 长岛县| 依兰县| 镇原县| 曲松县| 诸暨市| 剑川县|