程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JBuilder 2005 Struts深度體驗之新增

JBuilder 2005 Struts深度體驗之新增

編輯:關於JAVA

新增一個Struts配置文件

考慮到圖書模塊是一個比較獨立的模塊,為了避免對Struts配置文件的資源爭用導致團隊工程的覆蓋或沖突,我們為這個模塊單獨提供一個新的Struts配置文件,用這個配置文件配置圖書模塊所有Struts關聯的信息。

我們按照如下的方式為webModule模塊添加一個名為book-struts-config.xml的配置文件。

首先到<工程目錄>/webModule/WEB-INF拷貝一個原有的struts-config.xml文件,更名為book-struts-config.xml放在struts-config.xml相同的目錄下,刪除原有配置的內容,將其調整成:

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

然後,在工程窗格的資源樹中定位到webModule->Deployment descriptors-><Struts 1.1>節點上,右擊<Struts 1.1>節點,在彈出的菜單中選擇Properties...彈出Properties for ’<Struts 1.1>’對話框,如圖 16所示:

圖 16 Struts配置文件維護對話框

點擊Add...按鈕,在彈出的Choose Struts config file對話框中選擇book-struts-config.xml配置文件,按OK這個新的Struts配置文件將添加到Struts config file in web.xml列表中。

新增配置文件成功後,在工程窗格資源樹的<Struts 1.1>節點下,你將會發現這個新加入的Struts配置文件,如下圖所示:

圖 17 兩個Struts配置文件

這樣,在創建新的FormBean或Action時,你就可以選擇用哪個配置文件來保存Struts的配置信息了。

圖書Action Form

下面我們著手創建用於接收新增圖書頁面表單數據的BookActionForm,使用book-struts-config.xml保存BookActionForm的配置信息。BookActionForm需要進行數據有效性自檢,也就是說,要讓BookActionForm實現validate()方法。

創建BookActionForm和創建UserActionForm相似,但是在向導的第1步需要指定book-struts-config.xml記錄BookActionForm配置信息,如圖 18所示:

圖 18 選擇不同的配置文件

我們在前一節為Web模塊添加了一個配置文件,在Struts config下拉框中列出了Web模塊所有配置文件,這裡我們選擇WEB-INF/book-struts-config.xml。

在向導的第2步,我們為BookActionForm定義下列5個屬性:

String bookId;//圖書ID,對應T_BOOK表的BOOK_ID,是主鍵。
String isbn;//isbn
String createDate;//創建日期
String bookName;//書名
String author;//作者

在向導的第2步直接按Finish創建BookActionForm。由於bookId屬性是主鍵,所以不能和T_BOOK中已有的記錄重復,這可以通過BookActionForm的數據自檢機制來完成,數據自檢是通過定義validate()方法來實現的。向導已經為BookActionForm生成了validate()方法框架,我們只需要在validate()方法編寫bookId的校驗的代碼就可以了,BookActionForm的最終代碼如代碼清單 10所示:

代碼清單 10 BookActionForm.java

1. package bookstore;
2.
3. import javax.servlet.http.HttpServletRequest;
4. import org.apache.struts.action.*;
5. import java.sql.*;
6.
7. public class BookActionForm
8.  extends ActionForm {
9.   …
10.   public ActionErrors validate(ActionMapping actionMapping,
11.   HttpServletRequest httpServletRequest) {
12.    ActionErrors errors = new ActionErrors();
13.    Connection conn = null;
14.    try {
15.     conn = DBConnection.getConnection();
16.     PreparedStatement pStat = conn.prepareStatement(
17.      "select count(*) count from T_BOOK where BOOK_ID=?");
18.     pStat.setString(1, this.bookId);
19.     ResultSet rs = pStat.executeQuery();
20.     if (rs.next()&& rs.getInt(1) > 0) {
21.      errors.add("bookId ",
22.      new ActionMessage("bookstore.duplicate.bookId",
23.      "圖書ID和數據庫中已經有的ID重復"));
24.     }
25.    }
26.    catch (SQLException se) {
27.     se.printStackTrace();
28.     errors.add("bookId",
29.     new ActionMessage("bookstore.dbaccess.error", "訪問數據庫時出錯"));
30.    }
31.    finally {
32.     try {
33.      if (conn != null) {
34.       conn.close();
35.      }
36.     }
37.     catch (SQLException ex) {
38.      ex.printStackTrace();
39.      errors.add("bookId",
40.      new ActionMessage("bookstore.dbaccess.error",
41.        "訪問數據庫時出錯"));
42.     }
43.    }
44.   return errors;
45.  }
46.
47.  public void reset(ActionMapping actionMapping,
48.   HttpServletRequest servletRequest) {
49.    this.createDate = getCurrDateStr();
50.   }
51.
52.  //獲取當前時間字符
53.  private static String getCurrDateStr() {
54.   SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
55.   return sdf.format(new Date());
56.  }
57. }

當用戶提交表單後,Struts框架自動把表單數據填充到ActionForm中,接著Struts框架自動調用ActionForm的validate()方法進行數據驗證。如果validate()方法返回的ActionErrors為null或不包含任何ActionMessage對象,表示通過驗證,Struts框架將ActionForm和HTTP請求一起傳給Action的execute(),否則Struts框架將HTTP請求返回到輸入的頁面中,而輸入頁面即可通過<html:errors>顯示對應request域中的ActionErrors錯誤信息顯示出來。

此外,我們在reset()方法中將createDate屬性置為當前的日期,因為這個屬性值不是通過頁面表單提供的。

新增圖書JSP頁面

1.通過向導創建bookAdd.jsp

通過JSP向導創建bookAdd.jsp頁面,在向導的第2步選擇使用Struts1.1的struts-bean和struts-html標簽,如圖 19所示:

圖 19 指定選用Struts標簽

2.使用JBuilder的Struts標簽構建JSP頁面

你可以直接用拖拽的方法從JBuilder編輯器左邊的標簽庫將Struts標簽添加到JSP頁面中,如圖 20所示:

圖 20 用拖拽的方式添加Struts標簽

Struts的html標簽可以完成和標准的HTML元素相同的功能,Struts提倡使用Struts html標簽庫,因為這些標簽可以和Struts框架的其他組件緊密地聯系起來。而Strtus的bean標簽庫可以訪問已經存在的JavaBean及其屬性,有一些bean標簽還可以訪問HTTP請求頭信息及Web資源文件的信息。

我們希望用Struts的html標簽庫創建添加圖書的表單,通過bean標簽庫訪問Web資源文件作為表單組件前的標識文字。

bookAdd.jsp的最終代碼如代碼清單 11所示:

代碼清單 11 bookAdd.jsp

1. <%@page contentType="text/html; charset=GBK" %>
2. <%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
3. <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
4. <html>
5. <head>
6. <title>bookInsert</title>
7. <script language="JavaScript" >
8. function mySubmit(form)
9. {
10. if(form.isbn.value == null || form.isbn.value == "")
11. {
12.  alert("圖書的ISBN不允許為空");
13.  return false;
14. }
15. if(form.bookName.value == null || form.bookName.value == "")
16. {
17.  alert("圖書名不允許為空");
18.  return false;
19. }
20. }
21. </script>
22. </head>
23. <body bgcolor="#ffffff">
24. <html:errors/>
25.  <html:form action="/bookInsertAction.do" focus="bookId" method="post"
26.   onsubmit="return mySubmit(this)" >
27.  <table width="100%%" border="0">
28.   <tr>
29.    <td>
30.     <bean:message bundle="bookstore" key="bookstore.bookId"/>
31.    </td>
32.    <td>
33.     <html:text name="bookActionForm" property="bookId"/>
34.    </td>
35.    <td>
36.     <bean:message bundle="bookstore" key="bookstore.isbn"/>
37.    </td>
38.    <td>
39.     <html:text name="bookActionForm" property="isbn"/>
40.    </td>
41.   </tr>
42.   <tr>
43.    <td>
44.     <bean:message bundle="bookstore" key="bookstore.bookName"/>
45.    </td>
46.    <td>
47.     <html:text name="bookActionForm" property="bookName"/>
48.    </td>
49.   <td>
50.   <bean:message bundle="bookstore" key="bookstore.author"/>
51.   </td>
52.   <td>
53.    <html:text name="bookActionForm" property="author"/>
54.   </td>
55.  </tr>
56.  <tr align="center">
57.   <td colspan="4">
58.    <html:submit value="保存"/>
59.    <html:reset value="取消"/>
60.   </td>
61.  </tr>
62.  </table>
63. </html:form>
64. </body>
65. </html>

其中第25~63行是表單的定義代碼,將<html:form>的action指定為"/bookInsertAction.do", 它是BookInsertAction的訪問URI,將在下一節實現,通過<html:form>訪問Action時,action只需保證和配置文件中指定的path一致就可以了,無需在前面添加上諸如/webModule的Web部署子目錄。

在第26行我們為<html:form>指定了一個onsubmit客戶端校驗函數,當isbn和bookName兩組件中的任何一個為空時,拒絕提供表單。

我們定義了4個<html:text>,它們對應標簽HTML的<input type="text">輸入框標簽,其中name屬性為對應的ActionForm名字,而property對應ActionForm的屬性。圖 21是bookAdd.jsp的設計期效果圖:

圖 21 bookAdd.jsp設計時的界面圖

當然,你可以直接在表單組件前寫入具體的標識,如"圖書ID",而非第30行的<bean:message>標簽,但後者通過一個資源文件產生具體的標識,這樣不但可直接通過資源文件控制標識還提供了國際化的特性。

上面,我們只是簡單地引用了名為bookstore的資源文件,下面我們需要創建這個資源文件並在Struts配置文件中描述它。

到<工程目錄>/src目錄下,創建一個名為bookStoreResource_zh_CN.properties的資源文件,其內容如下所示:

bookstore.bookId=\u56fe\u4e66IDbookstore.isbn=ISBNbookstore.bookName=_
\u56fe\u4e66\u540dbookstore.author=\u4f5c\u8005bookstore.dbaccess.error=_
\u6570\u636e\u5e93\u8bbf\u95ee\u9519\u8befbookstore.duplicate.bookId=_
\u56fe\u4e66\u7f16\u53f7\u548c\u6570\u636e\u5e93\u4e2d\u5df2\u6709\u7684\u7f16\u53f7\u91cd\u590d

這兒的中文必須采用Unicode編碼格式,其對應的中文文件的內容為:

bookstore.bookId=圖書IDbookstore.isbn=ISBNbookstore.bookName=圖書名
bookstore.author=作者bookstore.dbaccess.error=數據庫訪問錯誤
bookstore.duplicate.bookId=圖書編號和數據庫中已有的編號重復

在編譯工程時,JBuilder會將位於<工程目錄>/src下的資源文件拷貝到Web模塊的WEB-INF/classes目錄下。

提示:

JDK提供了一個將中文轉換為Unicode編碼格式的工具native2ascii.exe,它位於<JDK>/bin/目錄下。在DOS命令窗口下,通過native2ascii -encoding GBK <源文件>

<目標文件>即可以完成轉換。

注意:

在前文中,我們曾提到了JBuilder 2005的一個Bug,即Web模塊中的類或資源有時得不到同步,需要手工將類和資源拷貝到對應的目錄。如果你發現資源文件沒有同步到WEB-INF/classes目錄時,bookStoreResource_zh_CN.properties需要在編譯工程後手工拷貝到這個目錄下,否則Struts就無法找到資源了。

在工程窗格的資源樹中找到book-struts-config.xml雙擊打開其對應的Struts Config Editor,切換到Message Resources標簽頁,如所示:

圖 22 定義資源文件

通過Add...按鈕定義一個鍵名為bookstore的bookStoreResource資源文件。不同的語言環境的客戶端將會訪問不同的資源文件,如客戶端為中文環境時,將訪問bookStoreResource_ch_CN.properties,如果是英語的客戶端將訪問bookStoreResource_cn.properties資源文件,如果沒有找到對應語言的資源文件,將訪問默認的資源文件,這裡,默認資源文件為bookStoreResource.properties。<bean:message>的boudle即為Parameter欄定義的名稱。

實戰經驗:

筆者原來對Struts標簽是比較排斥的,因為雖說它本意希望將頁面展現邏輯和程序邏輯完美地分離開來。頁面設計的工作由頁面設計人員在Dreamweaver中完成,由於Dreamweaver不認識Struts的標簽,那些像<html:text>,<html:submit>等表單組件的Struts標簽在頁面設計時看不到效果,所見即所得的理念被無情的剝奪了,界面設計人員對包含Struts標簽的頁面常常感到如墮五裡霧中。

許多Struts開發人員一直夢寐以求,希望能得到一個Dreamweaver的Struts標簽擴展插件,讓頁面設計人員可以象標准的HTML組件標簽一樣設計頁面。FWA公司的Visual Tags for Struts插件終於使我們夢想成真。通過這一插件,可以將Dreamweaver完美地和Struts結合起來,使用Struts標簽的JSP頁面可以在設計期得到使用標准HTML標簽一樣的可視化效果。你可以通過http://www.fwasi.com/downloads/下載Visual Tags for Struts的試用版。圖 21的bookAdd.jsp效果界面,即是在Dreamweaver 2004中使用了Visual Tags for Struts插件後的效果頁面。

此外,有一點關於Struts標簽的事情也必須提及:Sun開發出了JSF頁面標簽,這和Struts的標簽在功能上是有重疊的,Struts 以後的版本將逐漸往JSF靠近,JSF的標簽可能將最終取代Struts自己的標簽,以實現天下大統。

創建BookInsertAction

下面,我們來創建BookInsertAction,在該Action中將圖書記錄添加到T_BOOK表中。如果操作成功定向到insertSuccess.htm操作成功頁面,如果在進行數據庫操作時發現SQLException,則轉向sqlFail.htm頁面。我們需要事先創建這兩個HTML頁面,為了簡單,僅在其中寫入報告操作成功和失敗的信息即可。

按3.2相似的方式創建BookInsertAction,用book-struts-config.xml記錄配置信息,在向導的第2步,將FormBean name指定為bookActionForm,Scope為request,將input JSP指定為/bookAdd.jsp,如圖 23所示:

圖 23 指出BookInsertAction的配置信息

按Finish直接創建BookInsertAction,JBuilder將打開Struts Config Editor顯示/bookInsertAction的流程,如圖 24所示:

圖 24 bookInsertAction流程

添加1個出口,名為success,路徑為/insertSuccess.htm。最終的/bookInsertAction的流程如圖 5所示。

代碼清單 12是BookInsertAction的代碼,它完成圖書添加,出口控制的操作:

代碼清單 12 BookInsertAction.java

1. package bookstore;
2.
3. import javax.servlet.http.*;
4. import org.apache.struts.action.*;
5. import java.sql.*;
6.
7. public class BookInsertAction
8. extends Action {
9.  public ActionForward execute(ActionMapping actionMapping,
10.  ActionForm actionForm,
11.  HttpServletRequest servletRequest,
12.  HttpServletResponse servletResponse)
13.  throws Exception
14.  {
15.   BookActionForm bookActionForm = (BookActionForm) actionForm;
16.   Connection conn = null;
17.   conn = DBConnection.getConnection();
18.   PreparedStatement pStat = conn.prepareStatement(
19.    " insert into T_BOOK1(BOOK_ID,ISBN,BOOK_NAME,AUTHOR,"+
20.    "CREATE_DATE) values(?,?,?,?,?)");
21.   pStat.setString(1, bookActionForm.getBookId());
22.   pStat.setString(2, bookActionForm.getIsbn());
23.   pStat.setString(3, bookActionForm.getBookName());
24.   pStat.setString(4, bookActionForm.getAuthor());
25.   pStat.setString(5, bookActionForm.getCreateDate());
26.   pStat.executeUpdate();
27.   return actionMapping.findForward("success");
28.
29.  }
30. }

BookInsertAction將bookActionForm的數據通過JDBC添加到T_BOOK表中,添加成功則轉向insertSuccess.htm頁面。有些觀察細致的讀者也許已經注意到BookInsertAction的execute()方法並未直接對SQLException進行處理,而是將異常拋出,如第13行所示。這裡,我們要用到Struts1.1的新功能:通過配置方式處理異常。

在工程窗格的webModule/Deployment descriptors/<Struts 1.1>下找到並雙擊book-struts-config.xml文件,調出的Struts Config Editor配置編輯器,切換到Global Exceptions標簽頁,如圖 25所示:

圖 25 異常處理配置

點擊Add...定義一個名為sqlexception的異常處理配置項,處理java.sql.SQLException異常,定義完這個配置項後,選中這個配置項,點擊Edit...切換到這個配置項的詳細設置頁面,如圖 26所示:

圖 26 異常處理配置窗口

在窗口下部切換到Source視圖頁中,這個異常配置項的配置信息如代碼清單 13所示:

代碼清單 13 SQLException的異常處理配置項

1. …
2. <struts-config>
3.  …
4.  <global-exceptions>
5.   <exception key="sqlexception" type="java.sql.SQLException"
6.    path="/sqlFail.htm"/>
7.  </global-exceptions>
8.  …
9. </struts-config>

第5~6行將/sqlFail.htm和java.sql.SQLException"掛接"起來,這樣程序中任何Action的execute()方法拋出的SQLException異常都將由sqlexception配置項處理。

在welcome.jsp頁面中添加一個調用bookAdd.jsp的鏈接,登錄系統後,通過這外鏈接調出bookAdd.jsp頁面,如圖 27所示:

圖 27 添加圖書頁面

填寫圖書記錄,點擊保存提交表單到/bookInsertAction的Action中,如果提供的圖書ID和T_BOOK中已有的BOOK_ID重復,則Struts總控制器將直接返回到bookAdd.jsp頁面中,由<html:errors/>報告錯誤信息。如果數據通過BookActionForm的自檢並成功添加到數據庫中,將最終轉向insertSuccess.htm頁面。

提示:

如果用Tomcat為Web服務器,如果圖書記錄會出現中文亂碼的問題,可以使用我們上面介紹過的一個編碼過濾器,你可以在web.xml中配置這個過濾器,亂碼問題就可以解決了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved