(八)Struts標籤基礎(一)

1、Struts標籤分類

 

2、標籤的使用

  2.1  標籤的主題

  • 主題的設置與struts.xml中的常量<constant name="struts.ui.theme" value="xhtml" /> 決定。
  • 每一個主題都會對一些標籤產生做用,而這些做用被定義在一些文件文件裏,好比

    checkbox.ftl這個文件定義的是對checkbox標籤產生做用的語法。css

     

  • 主題共有如下幾種(版本爲struts2-core-2.3.14.jar):

路徑爲:struts2-core-2.3.14.jar包裏的html

    2.1.1  默認主題即template.xhtml , 會給標籤自動添加一些屬性或者子標籤,可能打亂咱們設計好的佈局

<body>
    <pre>
        <h3>默認主題</h3>
    <table border="1">
<tr> <td>用戶名</td> <td> <s:textfield></s:textfield> </td> </tr>
    </table>
</pre> </body>
  • 咱們本來的設計是這個表格一共一行且只有兩個空格, 可是結果爲:

  • 出現這種狀況是由於,template.xhtml這個主題會自動幫標籤添加一些屬性或子標籤,查看源代碼可知產生了td和tr子標籤:


 

   2.1.2  simple主題(最經常使用),額外添加的標籤不多,不會對咱們的佈局產生大的影響。

  •  在struts.xml中設置常量<constant name="struts.ui.theme" value="simple" />

 index.jspjava

<body>
    <pre>
        <h3>默認主題</h3>
        <table border="1">
        <tr>
            <td>用戶名</td>
            <td> <s:textfield></s:textfield>  </td>
        </tr>
        </table>
    </pre>
</body>

查看源碼:mysql

  • 對比咱們的代碼,文本框只添加了name屬性
  • 注意:在編寫頁面標籤的時候,最好先把主題設置爲simple主題,不然在佈局的時候會很麻煩。

    2.1.3  定製主題

  •   步驟: 
    •   在src目錄下新建一個文件夾,叫template (template名不能改爲別的)
    •   在template中在新建一個文件夾,名字自定義。
    •   在自定義的文件夾中,將要修改的控制的ftl文件拷貝,進行修改。好比咱們定製的主題中有對文本輸入標籤進行設定,那麼咱們就能夠到simple這個主題裏找到text.ftl這個文件(注意:text.ftl這個文件主題系統會自動做用在文本框裏,若是換成別的名字則沒法起做用),而後拷貝到咱們自定義的文件夾裏,再對text.ftl這個文件進行修改。
    • 把text.ftl中須要添加的文件添加進來,text.ftl須要如下四個文件,而後在simple主題中找到這四個文件而後拷貝到自定義文件夾裏便可。

    •   修改text.ftl  

紅框內的內容是咱們添加的css屬性。sql

    •   最後在標籤中應用此主題,<s:textfield theme="self"></s:textfield>  //self爲tempalte包的主題包名,由於這裏咱們只定義了一個標籤的主題,若是咱們在在self自定義主題包裏對大量標籤進行了主題設定,那麼我沒必要每一個標籤都使用theme屬性來引入主題,只須要struts.xml中設置常量<constant name="struts.ui.theme" value="self" /> 便可。

 

 結果:數據庫

可知標籤主題已經變成咱們自定義的了。apache


 

  2.2  表單標籤

    2.2.1  爲何要使用表單標籤?(struts表單標籤和input標籤的區別)

  • struts表單標籤能夠與Action中的屬性進行綁定,能夠實現屬性值到控件的Value值回填的操做。
  • 示例:
  • index.jsp:
<body>
    <a href="<%=path%>/tag/form">表單標籤</a>
</body>
  • struts.xml
<struts>

       <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    <constant name="struts.multipart.maxSize" value="209715200"></constant>
    <constant name="struts.action.extension" value="action,,"></constant>
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.i18n.reload" value="true"></constant>
    <constant name="struts.ui.theme" value="simple" />
    <constant name="struts.configuration.xml.reload" value="true"></constant>
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    <constant name="struts.handle.exception" value="true"></constant>

    <package name="default" namespace="/tag" extends="struts-default">
        <action name="form" class="tag.FromAction">
            <result name="formjsp">/tag/form.jsp</result>
        </action>
    </package>
</struts>
  • FromAction .java
package tag;

public class FromAction {
    private String textName;
    
    public String getTextName() {
        return textName;
    }

    public void setTextName(String textName) {
        this.textName = textName;
    }

    public String execute(){
        
        this.textName="Action對成員變量textNam賦值後會自動回填到表單中";
         return "formjsp";
    }

}
  • form.jsp
<body>    
    <pre>
        <s:textfield name="textName"></s:textfield>
    
    </pre>
</body>

結果:數組

  • 由結果可知,咱們在Action中設置了一個成員變量textName,而這個成員變量名和<s:textfield name="textName"></s:textfield>是同樣的,因此當咱們在Action中對textName進行賦值的時候,struts會自動把值回填到<s:textfield name="textName"></s:textfield>標籤裏。 而若是在input標籤中要實現數據的回填,則要在servlet中把值存放在做用域中,而後在jsp頁面裏用el表達式顯示出來才行。
  • input標籤實現數據回填:

      把值存放在做用域中 :request.setAttribute("屬性", "input標籤實現數據回填");jsp

     在jsp頁面中把值取出來並顯示: <input type="text" value="${requestScope.屬性}"/>或者 <input type="text" value="<s:property value="#request.屬性"/>"/>(request.setAttribute會吧屬性放在廣義值棧中的非狹義值棧的位置,因此須要用#來取值)。工具

 

  2.1.2  struts表單標籤的分類

 

    •  文本框標籤:<s:textfield name="textName"></s:textfield>  name屬性用來與Action中的成員變量綁定,請查看上例。
    •   文本域標籤:<s:textarea  name="remark"></s:textarea>
    •   密碼框標籤:<s:password name="passWd"></s:password>
    •   靜態單選框_1 :
      <tr>
              <td>靜態單選框:</td>
              <td>
      <s:radio list="{'男','女'}" name="sex_1"></s:radio></td>
          </tr>

      靜態單選框中的list屬性是必填的,list裏的{}是OGNL表達式,意思是定義一個集合,本題中{'男','女'}意思是定義一個集合且這個集合中有兩個string值。且list中集合有幾個值那麼就有幾個單選按鈕。以下圖,每一個單選按鈕的值對應着集合中的值,如右下圖。

 

    •   靜態單選框_2 :單選框的值由咱們來設置,而不是靜態單選框_1 由集合的值來定義。這裏用的是OGNL表達式中的「#{}」 表示定義一個MAP集合。
<tr>
        <td>靜態單選框_2:</td>
        <td><s:radio list="#{1:'男',0:'女'}" name="sex_1" ></s:radio></td>
    </tr>

    map集合中的1表明按鈕value=「1」,表示若是用戶選擇的是「男」這個按鈕,提交到後臺的數據是「1」 ,另外一個按鈕也是如此,查看源碼:

 


 

  • 單選框使用:

在JSP頁面中建立單選按鈕radio的方法:

<s:radio list="#{'1':'先生','0':'女士'}" name="gender" value="1"/>

其中list中的鍵值對錶示全部的選項,value表示設置的默認值,若是這個默認值是從後臺傳過來的,能夠這樣設置:

<s:radio list="#{'1':'先生','0':'女士'}" name="gender" value="gender.id"/>

  

當list屬性爲Action傳過來的Map時 能夠自動顯示爲key-value形式

<s:radio list="%{map}" name="gender" value="gender.id "/>

當list屬性爲Action傳過來的List<Gender>時 須要添加 listKey listValue屬性  listKey對應提交到數據庫中的值  listValue對應顯示的文本

<s:radio list="%{list}" name="gender" value="gender.id" listKey="id" listValue="genderText""/>

 


 

    •   動態單選框_1: 按鈕value是從數據庫或者其餘地方獲取的。
  • 示例:從數據庫中讀取值。

  A、  設計數據庫並插入數據:

  B、 加載數據庫驅動jar包,使用數據庫開源工具包(ommons-dbutils-1.3.jar),能夠幫助咱們快速操做數據庫,編寫操做數據庫的工具類。

    B1. 編寫工具類,獲取數據庫的鏈接Connection conn,DBUtil.java :

package DBUtil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtil {
        private static final String DRIVER="com.mysql.jdbc.Driver"; 
        private static final String USER="root"; 
        private static final String PASSWD=""; 
        private static final String URL="jdbc:mysql://127.0.0.1:3306/user?useUnicode=true&characterEncoding=UTF-8"; 

static{
    try {
        Class.forName(DRIVER);
    } catch (Exception e) {
    
        throw new RuntimeException("沒法加載驅動包");
    }
}
 
 public static Connection getConn(){
     Connection conn=null;
     try {
        conn= DriverManager.getConnection(URL,USER,PASSWD);
    } catch (SQLException e) {
        e.printStackTrace();
    }
    
     return conn;
 }
}

  B2. 使用數據庫開源工具包(ommons-dbutils-1.3.jar),這個包的類提供了快速增刪改查方法的實現。FormAction.java

package tag;

import java.util.List;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.opensymphony.xwork2.ActionContext;

import DBUtil.DBUtil;
import actionUtil.BaseAction;
import bean.UserBean;

public class FromAction extends BaseAction{
/**
 * QueryRunner類爲數據庫開源工具包(ommons-dbutils-1.3.jar)封裝的類,
 * 這個類實現了快速對數據庫操做的方法。
 * 步驟: 
 * 確認sql語句肯定相應的方法,本題中select * 查詢結果應該是一個集合。因此應該用QueryRunner的query()方法,
 * 而query()方法裏的三個參數爲「Connection conn,String sql,ResultSetHandler<T> t」其中ResultSetHandler
 * 是一個接口,咱們往query()方法裏填的參數不多是接口而只能是其實現類,其中ResultSetHandler<T>的實現類BeanListHandler<T>類
 * 是本題中須要的類,把這個類的對象加到query()方法裏,這個方法將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List裏,也就是說咱們
 * 此時還須要建立一個javaBean類,這個類的成員屬性(要有getset方法)要跟數據庫中的列名一致。
 * 
 */

    public String execute() throws Exception{
        ActionContext actionContext=ActionContext.getContext();
        
        String sql="select * from user order by userId";
        QueryRunner query=new QueryRunner();
        List<UserBean> list=query.query(DBUtil.getConn(), sql, new BeanListHandler<UserBean>(UserBean.class));
        actionContext.put("list", list);

         return "formjsp";
    }

}
  • 補充:ResultSetHandler的各個實現類:
    ArrayHandler:把結果集中的第一行數據轉成對象數組。
    ArrayListHandler:把結果集中的每一行數據都轉成一個對象數組,再存放到List中。
    BeanHandler:將結果集中的第一行數據封裝到一個對應的JavaBean實例中。
    BeanListHandler:將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List裏。//重點
    MapHandler:將結果集中的第一行數據封裝到一個Map裏,key是列名,value就是對應的值。//重點
    MapListHandler:將結果集中的每一行數據都封裝到一個Map裏,而後再存放到List
    ColumnListHandler:將結果集中某一列的數據存放到List中。
    KeyedHandler(name):將結果集中的每一行數據都封裝到一個Map裏(List<Map>),再把這些map再存到一個map裏,其key爲指定的列。
    ScalarHandler:將結果集第一行的某一列放到某個對象中。//重點

   

 B3. 在jsp頁面把值取出來  from.jsp

<tr>
        <td>靜態單選框_2:</td>
        <td><s:radio list="#list" name="sex_1" listKey="userId" listValue="userName"></s:radio></td>
    </tr>
  • list="#list" 表示往非廣義值棧裏取值爲list的屬性值(此時list存放的是javaBean對象的地址,因此取出來的也是地址),listValue="userName" 表示標籤的屬性value爲javaBean對象的userName屬性,

listKey="userId" 表單當用戶選中某個選項的時候返回到後臺的值。

 

結果:

參考剛纔數據庫裏的數據



  • 動態單選框_2: 按鈕value是從數據庫或者其餘地方獲取的。(與動態單選框_1相似)
    •   在上例中,把DBUtil.java 文件修改以下(只是把上例的list轉爲Map):
      package tag;
      
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      import org.apache.commons.dbutils.DbUtils;
      import org.apache.commons.dbutils.QueryRunner;
      import org.apache.commons.dbutils.ResultSetHandler;
      import org.apache.commons.dbutils.handlers.BeanListHandler;
      
      import com.opensymphony.xwork2.ActionContext;
      
      import DBUtil.DBUtil;
      import actionUtil.BaseAction;
      import bean.UserBean;
      
      public class FromAction extends BaseAction{
      /**
       * QueryRunner類爲數據庫開源工具包(ommons-dbutils-1.3.jar)封裝的類,
       * 這個類實現了快速對數據庫操做的方法。
       * 步驟: 
       * 確認sql語句肯定相應的方法,本題中select * 查詢結果應該是一個集合。因此應該用QueryRunner的query()方法,
       * 而query()方法裏的三個參數爲「Connection conn,String sql,ResultSetHandler<T> t」其中ResultSetHandler
       * 是一個接口,咱們往query()方法裏填的參數不多是接口而只能是其實現類,其中ResultSetHandler<T>的實現類BeanListHandler<T>類
       * 是本題中須要的類,把這個類的對象加到query()方法裏,這個方法將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List裏,也就是說咱們
       * 此時還須要建立一個javaBean類,這個類的成員屬性(要有getset方法)要跟數據庫中的列名一致。
       * 
       */
      
          public String execute() throws Exception{
              ActionContext actionContext=ActionContext.getContext();
              
              String sql="select * from user order by userId";
              QueryRunner query=new QueryRunner();
              List<UserBean> list=query.query(DBUtil.getConn(), sql, new BeanListHandler<UserBean>(UserBean.class));
          
              Map<String,String> userMap=new HashMap<String, String>();
              
              if(list!=null){
                  /**
                   * 把List轉換爲Map
                   */
                  for(UserBean user:list){
                  String    userName=user.getUserName();
                  String    userId=user.getUserId();
                  userMap.put(userId, userName);
                      
                  }
              }
              actionContext.put("userMap", userMap);
              
              
               return "formjsp";
          }
      
      }

      form.jsp:

<tr>
        <td>靜態單選框_2:</td>
        <td><s:radio list="#userMap" name="sex_1" ></s:radio></td>
    </tr>
  • 此時就不用添加listValue和listKey屬性了,由於Map就是鍵值對。

 


 

    • 下拉框標籤:
      •   下拉框也有動態下拉框若是須要的話,能夠參考動態單選框_1/動態單選框_2,可是下拉框通常是固定的值,不必動態獲取。
<tr>
        <td>下拉框</td>
        <td><s:select list="{'福建','山東','河南'}" name="privince" headerKey="none" headerValue="---請選擇---"></s:select></td>
    </tr>

 

    • 下拉框分組:
    <tr>
        <td>下拉框分組</td>
        <td>
        <s:select list="{'福建','山東','河南'}" name="privince" headerKey="none"
            headerValue="---請選擇---">
            <s:optgroup list="#{1:'泉州',2:'莆田',3:'福州'}" label="福建" ></s:optgroup>
        </s:select>
        </td>
        </tr>
  • <s:optgroup >標籤只能放在<s:select>標籤裏,且list只能用"#{}"這個OGNL表達式也就是必定要用Map,不然錯誤。

label標籤不可選定。


      • 複選框標籤和複選框分組標籤:

本例的文件與動態單選框_1中的文件相同,只有最後的form.jsp頁面改爲下面

<tr>
        <td>複選框:</td>
        <td><s:checkbox  name="is_check" value="true"></s:checkbox></td>
    </tr>

    <tr>
        <td>複選框分組:</td>
        <td><s:checkboxlist list="#userMap" name="group"></s:checkboxlist></td>
    </tr>

結果:

 

  • 其中list="userMap"是數據庫的數據封裝爲Map對象,並且<s:checkboxlist>中的list和name屬性必定要寫,name若是沒寫ftl文件會報name屬性未定義這個錯誤。
  • <s:checkboxlist>中的list若是是List集合,那麼就要加listValue和listKey屬性。

  隱藏域和文件域名標籤

<tr>
        <td>隱藏域</td>
        <td><s:hidden name="userId"></s:hidden ></td>
    </tr>
    <tr>
        <td>文本域</td>
        <td><s:file name="userface"></s:file ></td>
    </tr>

結果:

 


    •  表單標籤:
<s:form name="" id="" action="" method=""></form>
    • 按鈕標籤:

  • struts中沒有普通按鈕標籤。

 

    •   上下下拉框(使用這個標籤要在<head>標籤裏定義<s:head />標籤,這個標籤用於引入上下下拉框等標籤所需的腳本文件)
    <tr>
        <td>上下下拉框</td>
        <td><s:updownselect list="{'1','2','3'}" name="text" cssStyle="width:60px"
        allowMoveDown="true" allowMoveUp="true" allowSelectAll="true" moveDownLabel="向下移動" moveUpLabel="向上移動" selectAllLabel="全選"
        ></s:updownselect></td>
    </tr>
  • 用法相似動態單選框_1和動態單選框_2

 

    •    選項傳輸下拉框(1. 使用這個標籤要在<head>標籤裏定義<s:head />標籤,這個標籤用於引入上下下拉框等標籤所需的腳本文件 2. 使用這個標籤的時候不能用submit按鈕提交,不然後臺取值的時候會所有取到而不是隻取用戶選定的,只能經過定義普通按鈕而後這個按鈕觸發一個javaScript腳本,在腳本里定義一個submit()方法提交)

 

 

    •    組合框標籤(1.使用這個標籤要在<head>標籤裏定義<s:head />標籤,這個標籤用於引入上下下拉框等標籤所需的腳本文件 2. 使用這個標籤的時候不能用submit按鈕提交,不然後臺取值的時候會所有取到而不是隻取用戶選定的,只能經過定義普通按鈕而後這個按鈕觸發一個javaScript腳本,在腳本里定義一個submit()方法提交)

相關文章
相關標籤/搜索