Struts2知識點總結大全

openkk 12年前發布 | 115K 次閱讀 Struts2 Web框架

Struts MVC框架

 

Web應用的分層

交互層(Interaction Layer),表現數據,收集數據,也就是視圖層,接受請求,通過處理層完成相應的響應。(V,C)

處理層(Processing Layer),完成數據的處理,也就是業務層(M)。

 

MVC設計模式(應用觀察者模式的框架模式)

M: Model(Business process layer),模型,操作數據的業務處理層,并獨立于表現層(Independent of presentation)。

V: View(Presentation layer),視圖,通過客戶端數據類型顯示數據,并回顯模型層的執行結果。

C: Controller(Control layer),控制器,也就是視圖層和模型層橋梁,控制數據的流向,接受視圖層發出的事件,并重繪視圖。

 

MVC框架的實現模型

 

模型一(Page-centric):

JSP+JavaBean,JSP既充當控制,又充當視圖,以頁面為核心,JSP使用jsp:useBean,它不能夠實現不同的頁面,顯示不同的數據,需要借助于中間類來調用JavaBean的方法才能實現。

 

模型二(Servlet-centric):

JSP+Servlet+JavaBean,以控制為核心,JSP只負責顯示和收集數據,Sevlet,連接視圖和模型,將視圖層數據,發送給模型層,JavaBean,分為業務類和數據實體,業務類處理業務數據,數據實體,承載數據,基本上大多數的項目都是使用這種MVC的實現模式。

 

StrutsMVC框架(Web application frameworks)

 

Struts是使用MVC的實現模式二來實現的,也就是以控制器為核心。

 

Struts提供了一些組件使用MVC開發應用程序:

Model:Struts沒有提供model類。這個商業邏輯必須由Web應用程序的開發者以JavaBean或EJB的形式提供

 

View:Struts提供了action form創建form bean, 用于在controller和view間傳輸數據。此外,Struts提供了自定義JSP標簽庫,輔助開發者用JSP創建交互式的以表單為基礎的應用程序,應用程序資源文件保留了一些文本常量和錯誤消息,可轉變為其它語言,可用于JSP中。

 

Controller:Struts提供了一個核心的控制器ActionServlet,通過這個核心的控制器來調用其他用戶注冊了的自定義的控制器Action,自定義Action需要符合Struts的自定義Action規范,還需要在struts-config.xml的特定配置文件中進行配置,接收JSP輸入字段形成Action form,然后調用一個Action控制器。Action控制器中提供了model的邏輯接口。

 

寫一個基于Struts的web應用

 

1,創建一個符合標準的web應用的結構,也就是一個有WEB-INF文件夾的應用文件夾,在應用中需要使用到Struts的一些jar文件,要放到WEB-INF的lib文件夾下,這些jar文件都在struts的zip文件中的/struts-1.2.9-bin/lib下還有struts- 1.2.9-bin/contrib/struts-el/lib下的standard.jar、jstl.jar和struts-el.jar。

2,在web.xml中配置Struts的核心控制器ActionServlet,并指明Struts的配置文件的所在位置WEB-INF下,在 struts的文件中有一個樣板的web.xml文件,使用這個web.xml文件來部署應用就可以了 ,這個樣板在struts的zip文件中的struts-1.2.9-src.zip文件中的web/examples/WEB-INF/web.xml 就是樣板文件。部署應用看struts是否發布成功。

<servlet>

    <servlet-name>action</servlet-name>

    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

    <init-param>

      <param-name>config</param-name>

      <param-value>/WEB-INF/struts-config.xml</param-value>

    </init-param>

</servlet>

<servlet-mapping>

    <servlet-name>action</servlet-name>

    <url-pattern>*.do</url-pattern>

</servlet-mapping>

   

3,寫JSP頁面和業務,實體,和自定義控制器類Action,自定義Action是要繼承于Action類

例:

import org.apache.struts.action.*;

import javax.servlet.http.*;

 

public class LoginAction extends Action{

         public ActionForward execute(ActionMapping mapping, ActionForm form,

                   HttpServletRequest request,HttpServletResponse response) throws Exception

        {

                 if(request.getParameter("userName").equals("admin")&&

                              request.getParameter("passwd").equals("123")){

                     return mapping.findForward("success");

             }

             return mapping.findForward("fail");

    }

}

 

在struts-config.xml文件中的配置,解析配置文件中,配置文件的action標簽就會被映射成ActionMapping對象。

 

<struts-config>

  <form-beans>

     <form-bean name="xxx" type="ActionForm的類全名">

     <form-bean name="LoginForm" type="basic.LoginForm">

  </form-beans>

  <action-mappings>

     <action path="/basic/login"  type="alan.struts.basic.LoginAction"

                                  name="xxx" scope="request|sessio(默認值)">

        <forward name="success" path="/basic/success.jsp" redirect="true"/>

        <forward name="fail" path="/basic/fail.jsp" redirect="false"(重定向,默認false)/>

      </action>

    <action path="action的路徑,在form的action中寫的那個路徑" type="action的類全名">

      <forward name="在自定義的Action中使用的findForward方法的參數" path="跳轉頁面的路徑"/>

      <forward name="xxx" path="xxx/xxx.jsp"/>

    </action>

  </action-mappings>

</struts-config>

 

ActionForm是可以自動將表單中的數據封裝成對象,當然,一個自定義ActionForm也是要遵守Struts規范的,也就是要繼承于ActionForm,并在以上的struts-config.xml進行配置。

 

ServletController(ActionServlet和自定義的Action),配置Ctrler需要配置struts- config.xml,通過客戶端form的action來查找調用相應的action,自定義action中的mapping對應的是配置文件中的 forward標簽,通過forward的path屬性來跳轉到相應的路徑。

 

基于struts的web應用的開發步驟

    1. 對應用環境進行配置

    2. 創建web應用的結構,需要將struts應用的jar文件進行部署。

    3. 在web服務器部署struts

    4. 配置struts-config.xml文件,配置Action

5. 寫自定義Action,實體,以及業務類

 

 

ActionForm的校驗

 

<struts-config>

  <form-beans>

     <form-bean name="xxx" type="ActionForm的類全名">

     <form-bean name="LoginForm" type="basic.LoginForm">

     <!--配置ActionForm類-->

  </form-beans>

  <action-mappings>

     <action path="/basic/login"  type="alan.struts.basic.LoginAction"

                 name="xxx" scope="request|sessio(默認值)Form的保存空間">

        <forward name="success" path="/basic/success.jsp"/>

        <forward name="fail" path="/basic/fail.jsp" redirect="false"(重定向,默認false)/>

      </action>

   <action-mappings>

</struts-config>

 

ActionForm的校驗是struts提供的一項類似于Javascript的表單校驗的功能。他可以驗證用戶填寫的表單數據的正確性。

 

ActionForm的校驗,如果表單中的數據符不符合規定格式的要求,ActionForm的validate()方法會返回一個 ActionError對象,ActionError對象中封裝了一個或多個應用發現的校驗錯誤,每一個錯誤有一個ActionMessage對象表達,我們可以通過判斷這個ActionError的對象是否為空,如果為空那么表單的數據符合格式要求,不為空就是表單項中就有不符合格式要求的項。

 

struts標簽

 

在使用struts標簽的JSP頁面中要先加上以下的標簽庫的引用

<%@taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

 

<bean:message key="errors.username.required">這個標簽可以從指定的資源文件中根據指定的key值來取得可以對應的值,但是需要在struts-config.xml中進行配置。

配置資源,這些資源可以在ActionMessage中使用,也就是在構造ActionMessage是指定資源文件中的key這樣,在發現校驗錯誤時,就可以先在資源文件中指定的key的值了。可以使用struts的<html:errors>

<html:message>、<bean:message>標簽都可以顯示指定錯誤的消息。

<struts-config>

    .....

    <message-resources parameter="alan.struts.message.MessageResource" />

    <!--使用message標簽時配置資源文件的位置-->

</struts-config>

 

struts會自動的判斷返回ActionError是否為空,如果是空可以自動的轉向指定頁面,也可以強制不進行校驗,雖然可以在Form中不去覆蓋validate()方法,但是那樣是不可取的。要實現上面提得到功能還需要在struts-config中配置。

<action   path="/basic-validate/login"  type="alan.struts.basic.LoginAction"

                           name="loginValidateForm" scope="request"

                           validate="true"  input="/basic-validate/login.jsp">

    <!--scope可以指定Form的存放空間,默認為sessoin-->

    <!--action標簽中配置validate="false"可以不進行校驗,input是指定校驗出錯跳轉的頁面-->

    <forward name="success" path="/basic-validate/success.jsp"/>

    <forward name="fail" path="/basic-validate/fail.jsp"/>

</action>

 

<html:message id="error"><!--id屬性是ActionMessage存放在空間中的key-->

  <h1>${error}</h1>

</html:message>

<html:errors>標簽只會原樣輸出在ActionErrors中ActionMessage對應資源文件中對應的值。

<html:messages>標簽還可以對輸出在ActionError中ActionMessage對應資源文件中對應的值作一些顯示效果的修改。

<bean:message key="xxx.xxx">標簽只會取資源文件中指定key所對應的值,使用bean:message標簽可以實現國際化。

 

 

struts的html標簽

 

struts的html標簽的使用類似于html標簽,但是少有區別,指定類型的方式變成使用不同的標簽,這樣會綁定struts,所以旨在需要時使用。

<html:form method="post" action="/basic-validate/login">

<!--

   struts的html標簽中的action可以只寫轉到的actionpath,struts會在解析是自動添加需 要的部分 

-->

         <html:text property="userName" />

         <html:password property="password" redisplay="false"/>

        <!--redisplay="false"不進行回寫,只有html:password標簽可用-->

        <html:radio property="hibbos">

         <html:submit value="login" />

</html:form>

 

Struts預定義的Action類

 

注意:在使用繼承Struts預定義的Action類,一定不要覆蓋execute方法,否則會導致無法調用自定義Action相應方法。

 

DispatchAction類(org.apache.struts.actions.DispatchAction)

 

DispatchAction類是Action類的子類,他提供了有實現的execute方法。

 

我們寫的自定義Action類,可以繼承DispatchAction類,但不要覆蓋execute方法,可以在自定義類中寫反回值和參數表都與 execute方法相同的方法,可以通過在struts-congfig.xml中為這個action的配置中添加一個參數,來判斷調哪一個方法,實際上 DispatchAction類就是通過反射機制,通過form中參數調用了自定義Action中的方法,當然這些方法的定義要符合規范,使用繼承 DispatchAction類的自定義的Action類,也就會共享同一的Action路徑。

 

注意:使用繼承DispatchAction類的自定義的Action,只會匹配一個action路徑,只能共享一個ActionForm,如果加上校驗,會產生form表單的參數不一致的情況,會導致校驗無法通過。

 

 

例:

public class MyAction extends DispatchAction{

         ActionForward add(ActionForm form,HttpServletRequest request,HttpServletResponse                                         response ActionMapping mapping) throws Exception

        {

                    return mapping.findForward("sucess")                    

        }

}

 

<action path="/add"  type="MyAction" parameter="methodName">

    <!--parameter屬性是和form中隱藏域的名字相對應的-->

    <forward name="sucess" path="/sucess.jsp"/>

</action>

 

<from action="add.do" method="post">

   <input type="hidden" name="methodName" value="add"/>

   <!--

      使用隱藏域為struts傳遞要調用自定義Action中方法的方法名,是通過與struts-config.xml

      中action標簽中的parameter和name屬性相對應來獲取隱藏域的value。

   -->

   <input type="submit" value="submit"/>

</from>

 

MappingDispatchAction類(org.apache.struts.actions.MappingDispatchAction)

 

MappingDispatchAction類是DispatchAction的子類,他和DispatchAction不同點就是可以去匹配多個 action路徑,這樣也就是結決了共用ActoinForm的校驗問題了,多個Action的路徑使用同一的自定義Action類,這樣就不用共享同一個ActionForm,也就不會有校驗問題了。

 

 

例:

public class MyAction extends MappingDispatchAction{

         ActionForward add(ActionForm form,HttpServletRequest request,HttpServletResponse                                         response ActionMapping mapping) throws Exception

        {

                    return mapping.findForward("add")                    

        }

        ActionForward del(ActionForm form,HttpServletRequest request,HttpServletResponse                                         response ActionMapping mapping) throws Exception

        {

                    return mapping.findForward("del")                    

        }

}

 

<action path="/add"  type="MyAction" parameter="add">

   <!--parameter屬性是指定調用方法的名字-->

   <forward name="add" path="/add.jsp"/>

</action>       

<action path="/del"  type="MyAction" parameter="del">

   <forward name="del" path="/del.jsp"/>

</action>

 

在JSP頁面中也不用在使用隱藏域傳遞參數,直接在form中的action中就可以直接使用xxx.do匹配了。

<form action="add.do" method="post">

   <input type="submit" value="submit"/>

</form>

<form action="del.do" method="post">

   <input type="submit" value="submit"/>

</form>

 

LookupDispatchAction(org.apache.struts.actions.LookupDispatchAction)

 

LookupDispatchAction類也是DispatchAction類的子類,他所實現的功能是解決一個表單多種提交問題的

,他是通過使用資源文件,用submit按鈕的value來作為資源文件中的key所對應的值,通過這個值來找到對用的key,在使用這個key來獲得指定Map中所對應的值,這個值就是要調用的方法名。

 

submit的value---->MessageResource.properties中的key----->Map中key對相應的值---->action

 

例:

<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

 

<form method="post" action="${pageContext.request.contextPath}/lookup/adddel.do">

         <input type="submit" value="<bean:message key="button.add" />" name="methodName">

        <!--注意name="methodName"是和strut-config.xml中action標簽中的parameter屬性-->

         <input type="submit" value="<bean:message key="button.delete" />" name="methodName">

</form>

 

MessageResource.properties

 

button.add=add new user

button.delete=delete user

 

注意:在繼承LookupDispatchAction時,要覆蓋getKeyMethodMap()方法,并定義Map,向Map中放入指定的鍵值對。

 

public class AddDelLookupDispatchAction extends LookupDispatchAction

{

         public Map getKeyMethodMap(){

                  Map keyMethodMap= new HashMap();

                  keyMethodMap.put("button.add", "add");

                  keyMethodMap.put("button.delete", "delete");

                  return keyMethodMap;

         }      

    public ActionForward add(ActionMapping mapping,ActionForm form,

                   HttpServletRequest request,HttpServletResponse response) throws Exception

    {   

        return mapping.findForward("add");

    }

    public ActionForward delete(ActionMapping mapping,ActionForm form,

                   HttpServletRequest request,HttpServletResponse response) throws Exception

    {

             return mapping.findForward("delete");

    }

}

 

<action   path="/lookup/adddel"  type="alan.struts.actions.AddDelLookupDispatchAction"

                           parameter="methodName">

            <forward name="add" path="/add.jsp"/>

            <forward name="delete" path="/delete.jsp" />

</action>

<message-resources parameter="alan.struts.message.MessageResource" />

 

自定義的Action類的一些規則

1,盡量不要在Action類中使用(靜態)成員變量,如果使用要加上同步。

2,盡量使各模塊間的耦合性降低,最大限度的針對接口編程。

3,可以將共代碼方在覆蓋父類的方法中,最后可以用super.xxx(xxx)來調用父類的方法,使用父類的實現,并加上了自定義的功能。

 

 

Struts的Token(令牌)機制

 

Struts使用Token機制,來防止惡意的破壞和重復提交問題,也就是點擊后退后在再提交,這是Struts無法發現的,在form中生成一個 token碼,在session中也報村有一個同樣的token碼,當表單提交后,判斷兩個token碼向等后,就會改變session中的這個 token碼,當然在用回退后,form的token碼是不會變的,在提交,還會判斷兩個token碼是否相等,如果不等就會拋出異常,證明這是過時的垃圾數據。

 

void saveToken(HttpServletRequest request)方法用于將在客戶端生成的token碼,保存在session中。

void resetToken(HttpServletRequest request)方法用于重置token碼,生成新的token碼。

boolean isTokenValid(HttpServletRequest request,boolean reset)判斷token碼是否相等,并且是否重置token碼。reset是設定是否重置token碼,一般設為true。

 

設置token碼

 public ActionForward toadd(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response)throws Exception

    {

        saveToken(request);

        return mapping.findForward("next");

    }

 

驗證token碼

 public ActionForward add(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response)throws Exception

    {

        if(isTokenValid(request, true)){

            request.setAttribute("message", "contratulation!");

        } else {

            request.setAttribute("message", "sorry");

        }

        return mapping.findForward("next");

    }

 

 

Struts的異常處理

 

Struts只處理action的異常,

配置struts的異常處理

全局的異常處理

 

<global-exceptions>

   <exception key="error" path="xxx/xxx" type="xxx.xxx.Xxxx">

</global-exceptions>

 

<action path="xxx/xxx" type="xxx.xxx.Xxxx">

  ....

  <exception key="xxx" path="xxx/xxx" type="xxx.xxx.Xxxx">

</action>

在exception標簽中的key,也就是在出現異常時會封裝在ActionErrors中,也就是可以在頁面中使用。

ActionError(String key, Object value0),可以通過在構造ActionError時,指定不同的key值來對異常進行分類,并且在html:error標簽的

 

自己構造ActionErrors并使用下面的方法發送

 

void saveErrors(HttpServletRequest request,ActionErrors errors)這個方法用以把封裝了異常的ActionErrors的key存儲到request中。  

 

Struts動態Form

 

DynaActionForm,動態的ActionForm,動態的form不需要去寫特定的ActionForm類,只需要在配置文件中配置好form中的屬性名和屬性類型。以,Struts會自動的封裝成動態的Form。

 

<form-bean name="xxx" type="org.apache.struts.action.DynaActionForm">

   <from-property name="xxx" type="xxx.xxx.xxx">

   <from-property name="xxx" type="xxx.xxx.xxx">

     ...

     ...

</form-bean>

動態的ActionForm的使用上和普通的ActionForm相同。

在Struts中的Form要是粗粒度的,不要寫太多的Form,要根據情況確定Form的多少。

 

Struts的動態校驗

 

Struts可以通過繼承DynaActionForm,并覆蓋validate()方法來打倒校驗的目的。也可以通過配置校驗規則來進行動態Form的校驗實質上就是翻譯成javasctipt代碼。

使用校驗規則來進行動態校驗時需要寫validation.xml,validator-rules.xml

還需要對struts-config.xml進行配置

 

validation.xml

 

<form-validation>

  <formset>

    <form name="/token/add">

      <field property="name" depends="required,minlength, maxlength">

        <arg0 key="token.name" />

        <arg1 name="minlength" key="${var:minlength}" resource="false"/>

        <arg1 name="maxlength" key="${var:maxlength}" resource="false"/>

        <var>

          <var-name>minlength</var-name>

          <var-value>5</var-value>

        </var>

        <var>

          <var-name>maxlength</var-name>

          <var-value>8</var-value>

        </var>

      </field>

    </form>

  </formset>

</form-validation>

 

struts-config.xml

 

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

    <set-property

        property="pathnames"

        value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>

  </plug-in>

 

 

Struts的標簽

 

bean,html,logic標簽庫,在Struts的標簽也支持JSP2.0的EL表達式。

 

bean標簽庫

<bean:... >

bean標簽庫,是用來訪為JavaBean的屬性或者是為Bean的屬性賦值,創建JavaBean,類似于JSP中的jsp:useBean動作的功能。

bean標簽庫中的標簽中大部分都有以下的屬性

id="xxx" 指定Bean的名字標識,Bean在被讀出后將引用保存在以這個id命名的對象中,也就是在JSP中使用的變量的引用。

name="xxxx"指定要讀取Bean的名字

property="xxxx"

scope="page|request|session|application"

 

資源讀取標簽

<bean:resource>讀取資源文件

<bean:cookie>使用這個標簽可以對Cookie進行操作

<bean:header>讀取header信息

 

例:

<bean:resource id="indexpage" name="index.jsp"/>

<bean:write name="indexpage"/>

 

<bean:head id="head" name="user-agent"/>

<bean:write name="head"/>

 

<bean:cookie id="testcookie" name="/taglib/bean-cookie" value="emptyValue"/>

<%

         if(testcookie.getValue.equals("emptyValue")){

             javax.servlet.http.Cookie cook=new javax.servlet.http.Cookie("/taglib/bean-cookie","taglib cookie");

             cook.setComment("test");

             cook.setMaxAge(3600);

             response.addCookie(cook);

        }

%>

 

可以將資源寫到頁面的標簽

<bean:write>將Bean的屬性加入到輸出流中

<bean:write name="xxx"/>name屬性是要加入的資源,也就是先前在其他資源標簽中的id屬性定義的名字

 

<bean:define>定義變量

例:<bean:define id="test" value="test in Struts">

    <bean:write name="test"/>

 

<bean:message>讀取消息,可以根據key讀取消息。

例:

<bean:message key="org.test">

 

html標簽庫

 

<html:form>

 

對應html中的<form>,使用<html:form>會將表單中的屬性自動封裝成Form,他的action屬性可以直接寫struts的配置文件中的path

 

 

<html:text>、<html:password>、<html:textarea>、<html:hidden>、<html:submit>

<html:reset>、<html:checkbox>、<html:radio>、<html:select>、<html:option>

以上者寫標簽的使用是和html中的form相對應的。

 

<html:options>這個標簽用來表示一組選擇項

<%

   java.util.ArrayList list=new java.util.ArrayList();

   list.add(new org.apache.struts.util.LabelValueBean("show value","value"));

   list.add(new org.apache.struts.util.LabelValueBean("show value1","value1"));

   pageContext.setAttribute("vlauelist" list);

%>

<html:form action="xxx.do">

   <html:select property="test">

      <html:options collection="valuelist" property="value" labelProperty="label"/>

   </html:select>

</html:form>

 

 

Struts的Tiles框架

 

Tiles是一個框架,他實現了頁面的復合視圖,頁面代碼中不僅有數據,也有頁面的布局格式。

 

要在基于Struts應用中使用Tiles框架,就要在struts-config.xml中配置

<plugin className="org.apache.struts.tiles.TilesPlugin">

  <set-property property="definintions-config" value="/WEB-INF/tiles-defs.xml">

  <!--定義tiles布局文件tiles-defs.xml-->

</plugin>

 

tiles的布局配置文件tiles-defs.xml

 

<tiles-definitions>

    <!-- 頁面基本布局-->

    <definition name="pms_base" path="/common/pms_layout.jsp">

             <put name="title" value="pms title" />

        <put name="header" value="/common/header.jsp" />

        <put name="body"   value="some body page" />

        <put name="footer" value="/common/footer.jsp" />

    </definition>

   <!-- 其他頁面定義-->

   <definition name="add" extends="pms_base">

        <put name="title" value="add" />

        <put name="body" value="/person_add.jsp" />

    </definition>

</tiles-definitions>

 

在struts-config.xml中要把forward的配置更改一下

<action path="/person/toadd"  type="alan.pms.action.PersonAction"

                           name="personForm" scope="request"

                           parameter="toAdd">

            <forward name="add" path="add"/>

</action>

 

這樣就會使頁面加上header.jsp和footer.jsp顯示在配置好的頁面中

 

在頁面中使用tiles標簽時,要引入標簽庫,<%@taglib uri="/WEB-INF/tiles.tld" prefix="tiles"%>

 

<tiles:insert page="xxx.jsp">

   <tiles:put name="header" value="header.jsp">

   <tiles:put name="footer" value="footer.jsp">

</tiles:insert>

 

在struts-config.xml中要把forward的配置更改一下

<action path="/person/toadd"  type="alan.pms.action.PersonAction"

                           name="personForm" scope="request"

                           parameter="toAdd">

            <forward name="add" path="add"/>

</action>

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!