官术网_书友最值得收藏!

3.3 Struts 2入門案例

創建一個基于Struts 2的Web應用程序,需要完成以下5項工作。

1)創建Dynamic Web project工程,并搭建其支持Struts 2的開發環境。

2)設計模型層(設計有關的模型類),設計有關的業務邏輯處理。

3)設計控制層(設計有關的Action類),實現模型和視圖之間的交互。

4)設計視圖層(設計有關的JSP頁面),實現信息的提交與顯示。

5)修改映射文件struts.xml,在其中添加有關的Action和視圖類之間的映射。

3.3.1 入門案例1——基于Struts 2計算任意兩個數據的和

【例3-1】設計Web程序,其功能是用戶輸入兩個整數,提交給Action,在Action中計算這兩個數的和值,若和值為非負數,則跳轉到positive.jsp頁面,否則跳轉到negative.jsp頁面。運行界面如圖3-3所示。其中圖3-3a所示是輸入界面,而圖3-3b、圖3-3c所示是顯示結果界面。

圖3-3 【例3-1】的運行界面

a) 輸入界面b) 結果為非負數的輸出界面c) 結果為負數的輸出界面

【分析與設計】根據基于Struts 2開發的步驟,需要做的具體工作如下。

1)模型組件的創建:創建一個模型類Add.java,實現求和并保存和值。

2)控制器組件的創建:創建一個Action類AddAction.java,該類有一個屬性——Add add),利用該屬性,調用模型Add完成業務處理,并返回“頁面邏輯值”,當返回值為“-”時,表示計算結果為負數,否則,當返回值為“+”時,表示計算結果為非負數。

3)視圖組件的創建:視圖組件有3個JSP頁面:提交數據頁面(input.jsp),顯示結果為非負數的positive.jsp頁面,以及顯示結果為負數的negative.jsp頁面。

4)在配置文件struts.xml中,添加Action與視圖之間的映射關系,即AddAction與positive.jsp和negative.jsp之間的關系。

它們之間的邏輯關系如圖3-4所示。

圖3-4 【例3-1】的各組件之間的邏輯關系

【實現】按照設計步驟,依次實現。

1)創建Web工程struts2Add,并導入Struts 2必需的jar包(見3.2節)。

2)在web.xml中添加對Struts 2支持的核心控制器(具體配置信息見3.2節)。

3)編寫模型類:Add.Java(設計的類必須滿足JavaBean規范),其代碼如下。

4)設計業務控制類(Action類):AddAction.java。

該控制器的屬性為Add add,通過add接受用戶提交的數據x和y,計算并獲得sum值,該Action與網頁positive.jsp或negative.jsp共享數據add,其代碼如下。

5)修改struts.xml配置文件,添加Action的配置信息。

這些配置信息是Action與JSP頁面之間關聯的信息,其具體配置格式和配置內容將在后面給出詳細說明。

6)編寫JSP頁面:需要3個頁面:input.jsp、positive.jsp和negative.jsp。

① 提交數據頁面:input.jsp,主要代碼如下。

② 代數和為非負數時要跳轉到頁面positive.jsp,主要代碼如下。

③ 代數和為負數時要跳轉到頁面negative.jsp,主要代碼如下。

    <body>代數和為負整數,其和值為:${add.x}+${add.y}=${add.sum}</body>

7)將該工程添加到服務器Tomcat中并運行,運行界面如圖3-3所示。

提示:各組件實現數據共享是通過“Action容器”實現的,所以,在提交頁面和從Action實現的跳轉頁面中所共享的數據,必須與Action屬性一樣。

3.3.2 入門案例2——基于Struts 2實現用戶注冊與登錄

例3-2】在Web應用程序中,一般都需要實現用戶注冊與用戶登錄子系統。在本例中基于Struts 2開發設計用戶注冊與登錄功能。運行界面如圖3-5所示。

圖3-5 【例3-2】的運行界面

a) 主頁面b) 注冊頁面c) 注冊成功頁面d) 登錄頁面e) 登錄成功頁面f) 登錄失敗頁面

【分析與設計】

1)模型組件的創建。

該系統需要數據庫(MySQL數據庫),對數據庫進行操作,利用DAO模式,所以需要設計與數據庫有關的添加、查詢等操作的模型類和數據庫操作的通用類。

● DBConnection:實現數據庫連接和關閉的工具類。

● UserDao:實現數據庫操作的DAO業務類。

● EndUser:用戶JavaBean類,用于描述用戶信息及有關的處理方法。

2)控制器組件的創建。

創建Action類UserAction.java,包含用戶登錄方法和注冊方法,以及相關的屬性。

3)視圖組件的創建,視圖組件有8個JSP頁面。

● 登錄頁面(login.jsp):當需要登錄或者注冊時,顯示該頁面。

● 登錄成功頁面(login_success.jsp):用戶名和密碼都輸入正確,顯示該頁面。

● 登錄失敗頁面(login_failure.jsp):當用戶名或密碼不正確時顯示該頁面。

● 注冊頁面(register.jsp):當沒有注冊時,需要利用該頁面提交并注冊信息。

● 注冊成功頁面(register_success.jsp):當將注冊信息寫入數據庫后,顯示的頁面。

● 注冊失敗頁面1(register_failure_user.jsp):注冊時,若用戶已存在,提示重新注冊。

● 注冊失敗頁面2(register_failure.jsp):訪問數據庫出錯時,給出的提示頁面。

● 系統主頁面(index.jsp):當正確登錄后,進入系統的主頁面。

4)針對所要完成的模塊,單獨設計了一個滿足該模塊的struts配置文件:struts-user.xml,并且將該配置文件包含到struts.xml配置中。

這些組件之間的組織結構如圖3-6所示,其中圖3-6a是src目錄下的Java類和配置文件,圖3-6b是視圖目錄下的各JSP與web.xml文件。

圖3-6 【例3-2】各組件的組織結構圖

a) Java類和配置文件b) 視圖目錄下的各JSP與web.xml文件

這些組件是基于MVC的,它們之間的邏輯關聯關系如圖3-7所示。

圖3-7 【例3-2】的各組件之間的邏輯關聯關系

【Struts 2的關鍵思想】

在圖3-7中,視圖組件與Action組件之間是“數據耦合”的,如圖3-8所示。在登錄頁面和注冊頁面中分別輸入域屬性(name屬性),與Action類中的EndUser user屬性同名稱,這樣兩者之間就可以共享數據(在Action容器內共享)。圖3-8只給出了登錄過程中的數據共享示例,對于注冊過程是類似的,請讀者自己思考并給出。

圖3-8 數據之間的共享關系圖

【數據庫的設計】

該系統設計的數據庫為struts 2,其中的數據表為user,各數據字段如表3-1所示。采用MySQL數據庫,其中的數據庫密碼為123456,用戶名為root。

表3-1 數據表結構字段

【實現】按照設計步驟,依次實現。

1)在Eclipse中創建Web工程struts2user,并導入Struts 2必需的jar包。

2)修改web.xml配置文件,在web.xml中添加配置信息。

注意:這里的1)和2)兩步與【例3-1】一樣,不再詳述。

3)編寫模型類。

● 描述用戶信息EndUser類的實現,其代碼如下。

    package com.model.user;
    public class EndUser{
      private Integer userId;
      private String userName;
      private String userPassword;
      private String userRealName;
      //這里省略了所有屬性的setter/getter方法
    }

● 數據庫連接及關閉工具類DBConnection的實現,其代碼如下。

    package com.db_util;
    import java.sql.*;
    public class DBConnection {
      private static String driverName="com.mysql.jdbc.Driver"; //MySQL數據庫驅動程序
      private static String userName="root";  //數據庫用戶名
      private static String userPwd="123456"; //數據庫用戶密碼
      private static String dbName="struts2";  數據庫名稱
      public static Connection getDBConnection(){ //獲取數據庫連接對象的方法
        String url1="jdbc:mysql://localhost/"+dbName;
        String url2="? user="+userName+"&password="+userPwd;
        String url3="&useUnicode=true&characterEncoding=utf-8";
        String url=url1+url2+url3;    //形成數據庫連接字
        Connection con=null;
        try {
          Class.forName(driverName);   //加載驅動
          con=DriverManager.getConnection(url); //獲取數據庫連接對象
        } catch (Exception e) {e.printStackTrace(); }
        return con;
      }
      //關閉數據庫連接的各資源對象
      public static void closeDB(Connection con, PreparedStatement pstm, ResultSet rs){
        if(rs! =null) try {rs.close(); } catch (SQLException e) {e.printStackTrace(); }
        if(pstm! =null) try {pstm.close(); } catch (SQLException e) {e.printStackTrace(); }
        if(con! =null) try {con.close(); } catch (SQLException e) {e.printStackTrace(); }
      }
    }

● 數據庫操作的DAO類UserDao類的實現。

其代碼如下,這里只給出了兩個方法,即添加記錄和查找記錄的方法。

    package com.dao.user;
    //省略了import導入包;
    public class UserDao {
      public int save(EndUser user) { //向數據庫中插入一個用戶的方法
        Connection con=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        con=DBConnection.getDBConnection();
        int row=0;
        String sql="insert into user(userName, userPassword, userRealName) values(? , ? , ? )";
        try {
          pstmt=con.prepareStatement(sql);
          pstmt.setString(1, user.getUserName());
          pstmt.setString(2, user.getUserPassword());
          pstmt.setString(3, user.getUserRealName());
          row=pstmt.executeUpdate();
        } catch (Exception e) {e.printStackTrace(); }
        finally{DBConnection.closeDB(con, pstmt, rs); }
        return row;
      }
      public EndUser find(EndUser user) { //從數據庫中查找一個用戶,用于驗證是否注冊
        Connection con=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        con=DBConnection.getDBConnection();
        EndUser user2=null;
        String sql="select * from user where userName=? and userPassword=? ";
        try {
          pstmt=con.prepareStatement(sql);
          pstmt.setString(1, user.getUserName());
          pstmt.setString(2, user.getUserPassword());
          rs=pstmt.executeQuery();
          if(rs.next()){
            user2=new EndUser();
            user2.setUserId(rs.getInt("id"));
            user2.setUserName(rs.getString("userName"));
            user2.setUserPassword(rs.getString("userPassword"));
            user2.setUserRealName(rs.getString("userRealName"));
              }
          } catch (Exception e) {e.printStackTrace(); }
        finally{DBConnection.closeDB(con, pstmt, rs); }
        return user2;
      }
    }

4)設計控制類(Action類):UserAction.java。

該類利用模型層中的兩個類:EndUser和UserDao,給出對應的兩個屬性,通過Action方法實現所要求的功能,并利用user屬性實現與視圖層的數據共享。代碼如下。

    package com.action.user;
    //省略了import導入包;
    public class UserAction {
      private EndUser user;
      private UserDao userDao = new UserDao();
      public String userLogin() throws Exception {//用戶登錄Action方法
        String forward = null;
        EndUser user2 = userDao.find(user);
        if(user2! =null){forward="success"; }else{ forward="failure"; }
        return forward;
      }
      public String userRegister() throws Exception {//用戶注冊Action方法
        String forward="error";   //數據庫存數據時出錯標記值
        int flag = 0;
        EndUser user2=(userDao.find(user));
        if (user2! =null){forward = "error_user"; //用戶名已被占用標記標記值
        } else {
          flag = userDao.save(user);
          if (flag = = 1) {forward = "success"; //成功注冊標記值}
        }
        return forward;
      }
      //這里省略了屬性user的set/get方法,對于屬性UserDao userDao,不需要set/get方法
    }

5)配置Action形成單獨的配置文件struts-user.xml,并將其包含到struts.xml文件中。文件struts-user.xml的具體配置信息如下(注意該文件的格式與struts.xml一樣,這里省略了文件頭部分),在該配置中,配置了兩個Action。

將配置文件包含到struts.xml中,其內容如下。

    <struts>
        <include file="struts-user.xml" />
    </struts>

提示:這種配置方式是便于模塊化開發系統,每個模塊都有單獨的配置文件,易于維護和擴展。

6)編寫JSP頁面。

視圖組件有8個JSP頁面,這里只給出每個頁面的body標簽內的內容。

● 登錄頁面(login.jsp),當需要登錄或者注冊時,顯示的初始頁面。

    <body>
      <form method="post" action="/struts2user/user/logincheck">
      <table>
        <tr><th colspan="2">用戶登錄</th></tr>
        <tr><td align="right">用戶名:</td> <td><input name="user.userName" /></td> </tr>
        <tr><td align="right">密碼:</td>
          <td><input type="password" name="user.userPassword" /></td> </tr>
        <tr><td align="left"><input type="submit" value="登錄" /></td>
          <td>未注冊者,請先注冊,單擊<a href="/struts2user/user/register.jsp">注冊</a></td>
        </tr>
      </table>
      </form>
    </body>

● 登錄成功頁面(login_success.jsp),當用戶名和密碼都正確時,顯示該頁面。

    <body>
      歡迎你,${user.userRealName},你登入成功!! <br>
      進入主頁面,請點擊<a href="/struts2user/index.jsp">主頁面</a>
    </body>

● 登錄失敗提示頁面(login_failure.jsp),當用戶名或密碼不正確時,顯示該頁面。

    <body>
      <h2 align="center">
        <font color="red">對不起,你填寫的賬號和密碼不正確!請</font>
          <a href="/struts2user/user/login.jsp">重新登錄</a>
      </h2>
    </body>

● 注冊頁面(register.jsp),注意采用js腳本實現輸入驗證。

    <head><title>注冊頁面</title>
    <script type="text/javascript">
      function isValidate(form) {
        var username=document.getElementById("username").value;
        var userpass=document.getElementById("userpassword").value;
        var userpass1=document.getElementById("userpass1").value;
        if (userpass ! = userpass1) {
          alert("兩次密碼輸入不一致,請重新輸入!");
          return false;
        }else if (userpass.length<=0 ||username.length<=0 ) {
          alert("用戶名以及密碼不能為空,請重新輸入!");
          return false; }
        else{return true; }
      }
    </script></head>
    <body>
      <h3 align="left">歡迎注冊我們的系統,請認真填寫您的信息</h3>
      <form name="register" action="/struts2user/user/register"
                  method="post"  onsubmit="return isValidate()">
        <table>
          <tr><td align="right">賬戶名:</td>
            <td><input name="user.userName" id="username"></td></tr>
          <tr><td align="right">為您的賬戶設置密碼:</td>
            <td><input type="password"
                      name="user.userPassword" id="userpassword"></td></tr>
          <tr><td align="right">再次確認您的密碼:</td>
            <td><input type="password" name="userpass1" id="userpass1"></td></tr>
          <tr><td align="right">真實姓名:</td>
            <td><input  name="user.userRealName"id="userrealname"></td></tr>
          <tr><td align="right"><input type="submit" value="提交"></td>
            <td colspan="2"><input type="reset" value="重新填寫"></td></tr>
        </table>
      </form>
    </body>

對于頁面register_success.jsp、register_failure_user.jsp、register_failure.jsp、index.jsp與登錄成功、失敗頁面類似,這里就不再給出介紹。

本節通過兩個簡單的案例,較詳細地給出了基于Struts 2開發應用程序的思想、方法和步驟。這是深入學習和掌握Struts 2所必需的基礎知識。在后面的章節中,將Struts 2按MVC三層結構,分別給出M、C、V有關內容的詳細說明與應用設計。

提示:Struts 2的中文亂碼問題處理:在視圖頁面與Action進行信息交互時,若有中文字符,會出現亂碼問題。Struts 2中有兩種方法可以解決這個問題:①設置JSP頁面的pageEncoding="UTF-8"。②如果JSP頁面的pageEncoding="GBK",那么需要在源包(src)下建立一個屬性文件struts.properites,并在該文件內填寫如下內容,修改有關的屬性值:struts.locale=zh_CN, struts.i18n.encoding=gbk

主站蜘蛛池模板: 湖州市| 自治县| 横峰县| 沾化县| 石首市| 丰原市| 阳泉市| 齐河县| 宁陕县| 罗甸县| 榕江县| 渝中区| 青神县| 潞西市| 华阴市| 德阳市| 崇仁县| 定襄县| 东光县| 内丘县| 修文县| 南雄市| 光山县| 金华市| 兴海县| 茶陵县| 牡丹江市| 岳普湖县| 奇台县| 射洪县| 乡宁县| 五指山市| 东丽区| 林州市| 柏乡县| 德安县| 榆林市| 河北区| 武义县| 齐河县| 德昌县|