Struts1.x系列教程(1):用MyEclipse開發第一個Struts程序

本文爲原創,如需轉載,請註明作者和出處,謝謝!

本系列教程將詳細介紹
Struts 1.x的基本原理和使用方法,讀者可以參閱Struts 2系列教程》來比較Struts 1.xStruts 2.x的相同點和不同點。
在這篇文章中將以一個簡單的例子
(mystruts)來演示如何使用MyEclipse來開發、運行Struts程序,並給出瞭解決ActionForm出現亂碼問題的方法。讀者可以從本文中瞭解開發Struts 1.x程序的基本過程。

一、本文給出的程序要實現什麼功能


mystruts是一個錄入和查詢產品信息的程序。爲了方便起見,本例中的產品信息表只包括了產品ID、產品名稱和產品價格三個字段。mystruts的主要功能如下:

1. 接受用戶輸入的產品ID、產品名稱和產品價格。

2. 驗證這些字段的合法性。如果某些字段的輸入不合法(如未輸入產品ID),程序會forward到一個信息顯示頁,並顯示出錯原因。

3. 如果用戶輸入了正確的字段值,程序會將這些字段值保存到數據庫中,並顯示「保存成功」信息。

4. 用戶輸入產品名稱,並根據產品名稱進行模糊查詢。如果存在符合要求的產品信息。程序會以表格形式顯示這些產品的信息,同時顯示記錄數。如果未查到任何記錄,會顯示「沒有符合要求的記錄!」信息。

二、編寫程序前的準備工作

1. 建立數據庫

在編寫程序之前,需要建立一個數據庫( struts )和一個表 (t_products) ,建立數據庫和表的 SQL 腳本如下所示:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> #建立數據庫struts
CREATE DATABASE IF NOT EXISTS struts DEFAULT CHARACTER SET GBK;

#建立表t_products
CREATE TABLE IF NOT EXISTS struts.t_products(
product_id
varchar ( 4 ) NOT NULL ,
product_name
varchar ( 50 ) NOT NULL ,
price
float NOT NULL ,
PRIMARY KEY (product_id)
)ENGINE
= InnoDB DEFAULT CHARSET = gbk;

2建立一個支持struts1.xsamples工程

MyEclipse建立一個samples工程(Web工程),現在這個samples工程還不支持Struts1.x(沒有引入相應的Struts jar包、struts-config.xml文件以及其他和Struts相關的配置)。然而,在MyEclipse中這一切並不需要我們手工去加入。而只需要使用MyEclipse的【New Struts Capabilities】對話框就可以自動完成這些工作。

首先選中samples工程,然後在右鍵菜單中選擇【MyEclipse > New Struts Capabilities】,啓動【New Struts Capabilities】對話框。對默認的設置需要進行如下的改動:

(1)將Struts specification改爲Struts 1.2。

(2)Base package for new classes改爲struts

(3)Default application resources改爲struts.ApplicationResources

改完後的【New Struts Capabilities】對話框如圖1所示。



圖1

在設置完後,點擊Finish按鈕關閉對話框。在向samples工程添加支持Struts的功能後,主要對samples工程進行了三個操作。

1)引入了Struts 1.2 jar包(在samples的工程樹中多了一個Struts 1.2 Libraries節點)。

2)在WEB-INF目錄中添加了一個struts-config.xml文件。文件的默認內容如下面的代碼所示:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <? xmlversion="1.0"encoding="UTF-8" ?>
<! DOCTYPEstruts-configPUBLIC"-//ApacheSoftwareFoundation//DTDStrutsConfiguration1.2//EN"
"http://struts.apache.org/dtds/struts-config_1_2.dtd"
>
< struts-config >
< data-sources />
< form-beans />
< global-exceptions />
< global-forwards />
< action-mappings />
< message-resources parameter ="struts.ApplicationResources" />
</ struts-config >

3)在WEB-INF中的web.xml文件中添加了處理Struts動作的ActionServlet的配置,代碼如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < 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 >
< init-param >
< param-name > debug </ param-name >
< param-value > 3 </ param-value >
</ init-param >
< init-param >
< param-name > detail </ param-name >
< param-value > 3 </ param-value >
</ init-param >
< load-on-startup > 0 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > action </ servlet-name >
< url-pattern > *.do </ url-pattern >
</ servlet-mapping >

到目前爲止,samples工程已經完全支持Struts了。讀者可以看到,如果不使用MyEclipse,那麼上面所列出的配置文件的內容都必須手工輸入。因此,使用MyEclipse來開發Struts程序可以省去很多配置xml文件的工作。

三、實現程序的首頁(index.jsp)

首先在<samples工程目錄>中建立一個mystruts目錄,然後在<samples工程目錄>" mystruts目錄中建立一個index.jsp文件,這個文件的內容如下。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < %@page pageEncoding ="GBK" % >
< %-- 引用Strutstag--% >
< %@taglib uri ="http://struts.apache.org/tags-html" prefix ="html" % >
< html >
< head >
< title > 主界面 </ title >
</ head >
< body >
< table align ="center" cellpadding ="10" width ="100%" >
< tr >
< td align ="right" width ="50%" >
< %-- 使用Strutstag--% >
< html:link forward ="newProduct" > 錄入產品信息 </ html:link >
</ td >
< td >
< html:link forward ="searchProduct" > 查詢產品信息 </ html:link >
</ td >
</ tr >
</ table >
</ body >
</ html >

MyEclipse中啓動Tomcat(如果Tomcat處於啓動狀態,在修改完配置文件後,建議在MyEclipseServers頁重新發布samples工程,以使修改生效)。在IE中輸入如下的URL

http://localhost:8080/samples/mystruts/index.jsp

我們發現在輸入上面的URL後,在IE中並未顯示正確的運行結果,而是拋出瞭如下的異常:

java.net.MalformedURLException: Cannot retrieve ActionForward named newProduct

這個異常表明程序並未找到一個叫newProductforwardforward將在後面詳細地講述)。因此,可以斷定,在JSP中使用forward時,這個forward必須存在。下面我們來添加index.jsp頁面中所使用的兩個forwardnewProductsearchProduct。這兩個forward分別引向了建立產品信息的頁面(newProduct.jsp)和查詢產品信息的頁面(searchProduct.jsp)。我們可以在struts-config.xml文件中<struts-config>節點中添加兩個全局的forward,代碼如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < global-forwards >
< forward name ="newProduct" path ="/mystruts/newProduct.jsp" />
< forward name ="searchProduct" path ="/mystruts/searchProduct.jsp" />
</ global-forwards >

上面的代碼中所示的newProduct.jspsearchProduct.jsp目前並不存在(將在以後實現這兩個JSP頁面),現在重新輸入上述的URL,會得到如圖2所示的效果。



圖2

如果想讓index.jsp成爲默認的JSP頁面,可以在web.xml中的<welcome-file-list>節點中加入如下的內容:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < welcome-file > index.jsp </ welcome-file >

這時在IE中只要輸入如下的URL就可以訪問index.jsp頁面了。

http://localhost:8080/samples/mystruts

四、實現添加和查詢產品信息頁面

在本節中主要實現了用於輸入產品信息(newProduct.jsp)和查詢產品信息(searchProduct.jsp)JSP頁面。

newProduct.jsp頁面中有一個form,在form中含有三個文本框,用於分別輸入產品ID、產品名稱和產品價格。在<samples工程目錄>"mystruts目錄中建立一個newProduct.jsp文件,代碼如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <% @pagepageEncoding = " GBK " %>
<% @tagliburi = " http://struts.apache.org/tags-html " prefix = " html " %>
< html >
< head >
< title > 錄入產品信息 </ title >
</ head >
< body >
<% -- 向saveProduct動作提交產品信息 -- %>
< html:form action ="saveProduct" >
< table width ="100%" >
< tr >
< td align ="center" >
產品編號:
< html:text property ="productID" maxlength ="4" />
< p >
產品名稱:
< html:text property ="productName" />
< p >

產品價格:
< html:text property ="price" />
</ td >
</ tr >
< tr >
< td align ="center" >
< br >
< html:submit value ="保存" />
</ td >
</ tr >
</ table >
</ html:form >
</ body >
</ html >

searchProduct.jsp頁面中有一個form,爲了方便起見,在form中只提供了一個文本框用於對產品名稱進行模糊查詢。在<samples工程目錄>" mystruts目錄中建立一個searchProduct.jsp文件,代碼如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <% @pagepageEncoding = " GBK " %>
<% @tagliburi = " http://struts.apache.org/tags-html " prefix = " html " %>
< html >
< head >
< title > 查詢產品信息 </ title >
</ head >
< body >
<% -- 向searchProduct動作提交查詢請求 -- %>
< html:form action ="searchProduct" >
< table width ="100%" >
< tr >
< td align ="center" >
產品名稱:
< html:text property ="productName" />
</ td >
</ tr >
< tr >
< td align ="center" >
< br >
< html:submit value ="查詢" />
</ td >
</ tr >
</ table >
</ html:form >
</ body >
</ html >

現在啓動Tomcat,並使用如下兩個URL來訪問newProduct.jspsearchProduct.jsp

http://localhost:8080/samples/mystruts/newProduct.jsp
http://localhost:8080/samples/mystruts/searchProduct.jsp

IE中輸入上面的兩個URL後,並不能顯示出相應的界面,而會拋出JspException異常,表明未找到saveProductsearchProduct動作。從這一點可以看出,如果在JSP中使用Struts Action,這些Action必須事先在struts-config.xml文件中定義,否則,JSP程序就無法正常訪問。在這兩個頁面所使用的動作(saveProductsearchProduct)將會在下面的部分介紹。


五、通過模型類操作數據庫

在這一節我們來編寫用於操作數據庫的模型類。由於本例子是 Web 程序,因此,建議在連接數據庫時使用數據庫連接池。在 <Tomcat 安裝目錄 >"conf"Catalina"localhost 目錄中打開 samples.xml 文件(如果沒有該文件,則建立一個 samples.xml 文件),在 <Context> 節點中加入如下的內容:

配置連接池(用於連接數據庫struts

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < Resource name ="jdbc/struts" auth ="Container"
type
="javax.sql.DataSource"
driverClassName
="com.mysql.jdbc.Driver"
url
="jdbc:mysql://localhost:3306/struts?characterEncoding=GBK"
username
="root"
password
="1234"
maxActive
="200"
maxIdle
="50"
maxWait
="3000" />

本例中提供了兩個可以操作數據庫的模型類:ProductSearchProduct。其中Product用於驗證由客戶端提交的產品信息,並向t_products表中寫入這些信息。而SearchProduct類用於對t_products表的product_name字段進行模糊查詢,並返回查詢到的產品信息(包括產品ID、產品名稱和產品價格)。

由於 Product SearchProduct 都需要使用數據庫連接池來連接數據庫,因此,可以將連接數據庫的工作提出來作爲一個父類 (Struts ) 提供,代碼如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> package util;
import java.sql.Connection;
public class Struts
{
protected javax.naming.Contextctx = new javax.naming.InitialContext();
protected javax.sql.DataSourceds;
protected Connectionconn;
public Struts() throws Exception
{
ds
= (javax.sql.DataSource)ctx.lookup( " java:/comp/env/jdbc/struts " );
conn
= ds.getConnection(); // 從數據庫連接池獲得一個Connection
}
}

<samples 工程目錄 >"src 目錄中建立一個 Product.java 文件,代碼所示:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> package mystruts.model;

import java.sql. * ;
import mystruts.actionform. * ;

public class Product extends util.Struts
{
private ProductFormform;

public Product(ProductFormform) throws Exception
{
super ();
this .form = form;
validate();
}
// 驗證客戶端提交的數據
public void validate() throws Exception
{
if (form.getProductID().trim().equals( "" ))
throw new Exception( " 產品ID不能爲空! " );
if (form.getProductID().length() > 4 )
throw new Exception( " 產品ID最長爲4位! " );
if (form.getProductName().trim().equals( "" ))
throw new Exception( " 產品名稱不能爲空 " );
if (Float.compare(form.getPrice(), 0 ) <= 0 )
throw new Exception( " 產品價格必須大於0 " );
}
// 將客戶端提交的產品信息保存到t_products中
public void save() throws Exception
{
try
{
StringproductID
= form.getProductID();
StringproductName
= form.getProductName();
float price = form.getPrice();
Stringsql
= "