【原創】Struts1.x系列教程(1)-B:用MyEclipse開發第一個Struts程式

銀河使者發表於2009-01-13
本文為原創,如需轉載,請註明作者和出處,謝謝!

五、通過模型類運算元據庫

    在這一節我們來編寫用於運算元據庫的模型類。由於本例子是Web程式,因此,建議在連線資料庫時使用資料庫連線池。在安裝目錄>"conf"Catalina"localhost目錄中開啟samples.xml檔案(如果沒有該檔案,則建立一個samples.xml檔案),在節點中加入如下的內容:

配置連線池(用於連線資料庫struts

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  <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、產品名稱和產品價格)。

   由於ProductSearchProduct都需要使用資料庫連線池來連線資料庫,因此,可以將連線資料庫的工作提出來作為一個父類(Struts)提供,程式碼如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtpackage util;
import java.sql.Connection;
public class Struts
{
    protected javax.naming.Context ctx = new javax.naming.InitialContext();
    protected javax.sql.DataSource ds;
   
protected Connection conn;
   
public Struts() throws Exception
    {
        ds 
= (javax.sql.DataSource) ctx.lookup("java:/comp/env/jdbc/struts");
        conn 
= ds.getConnection();  // 從資料庫連線池獲得一個Connection
    }
}

    工程目錄>"src目錄中建立一個Product.java檔案,程式碼所示:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  package mystruts.model;
  
  
import java.sql.*;
  
import mystruts.actionform.*;
  
  
public class Product extends util.Struts
  {
      
private ProductForm form;
  
      
public Product(ProductForm form) 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
          {
              String productID 
= form.getProductID();
              String productName 
= form.getProductName();
              
float price = form.getPrice();
              String sql 
= "INSERT INTO t_products VALUES('" + productID + "',"
                      
+ "'" + productName + "'," + String.valueOf(price) + ")";
              PreparedStatement pstmt 
= conn.prepareStatement(sql);
              pstmt.executeUpdate();   
// 執行INSERT語句
              pstmt.close();
              conn.close();
          }
          
catch (Exception e)
          {
              
throw new Exception(e.getMessage());
          }
      }
  }

    Product類中使用了一個ProductForm類,這個類是一個ActionForm類,它的功能是儲存客戶端提交的資料。關於這個類將在下面詳細介紹。Product類通過構造方法的form引數將客戶端提交的資料傳入Product類的物件例項中,並在構造方法中驗證這些資料,如果發現資料不合法,就會丟擲一個異常。當客戶端提交的資料合法後,成功建立了一個Product類的物件例項,然後可以通過簡單地呼叫save方法將資料儲存到t_products表中。

    Product類似,在工程目錄>"src目錄中建立一個SearchProduct.java檔案,程式碼如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  package mystruts.model;
  
  
import java.sql.*;
  
import java.util.*;
  
import mystruts.actionform.*;
  
  
public class SearchProduct extends util.Struts
  {
      
private ProductForm form;
  
      
public SearchProduct(ProductForm form) throws Exception
      {
          
super();
          
this.form = form;
      }    
      
// 查詢產品資訊,並通過List返回查詢結果
      public List<String[]> search() throws Exception
      {
          List
<String[]> result = new LinkedList<String[]>();
          String sql 
= "SELECT * FROM t_products WHERE product_name like '%" 
+ form.getProductName() + "%'";
          PreparedStatement pstmt 
=  conn.prepareStatement(sql);
          ResultSet rs 
= pstmt.executeQuery();  // 開始執行SELECT語句
          while(rs.next())
          {
              String[] row 
= new String[3];
              row[
0= rs.getString(1);
              row[
1= rs.getString(2);
              row[
2= rs.getString(3);
              result.add(row);
          }
          rs.close();
          conn.close();
          
return result;
      }
  }

       SearchProduct類也使用了ProductForm類,但在SearchProduct中並不會驗證ProductForm物件例項中的資料,而只是將ProductForm物件作為傳遞查詢請求資訊(實際上只需要產品名稱)的工具而已。

六、實現控制器

   
在這一節要實現的控制器是基於StrutsWeb程式的核心部分之一:控制器實質上也是普通的Java類,但這個Java類一般要從org.apache.struts.action.Action類 繼承。控制器的主要功能是接受並處理從JSP頁面提交的資料、通過模型(Model)和資料庫互動以及forward到相應的頁面(可以是任何頁面,如 html、JSP和Servlet等)。在實現控制器之前,需要先實現一個ActionForm類, 這個類的作用是儲存JSP頁面提交的資料。在"src目錄中建立一個ProductForm.java檔案,程式碼 如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  package mystruts.actionform;
  
  
import org.apache.struts.action.*;
  
  
public class ProductForm extends ActionForm
  {
      
private String productID;  // 產品ID
      private String productName; // 產品名稱
      private float price;  // 產品價格
      public String getProductID()
      {
          
return productID;
      }
      
public void setProductID(String productID)
      {
          
this.productID = productID;
      }
      
public String getProductName()
      {
          
return productName;
      }
      
public void setProductName(String productName)
      {
          
this.productName = productName;
      }
      
public float getPrice()
      {
          
return price;
      }
      
public void setPrice(float price)
      {
          
this.price = price;
      }
  }

    從上面的程式碼可以看出,ActionForm類一般從org.apache.struts.action.ActionForm類繼承,而且在類中需要按著需要儲存的資料表欄位新增屬性。如產品ID的屬性是productName。在MyEclipse中可以只定義三個private變數,然後使用MyEclipse的Source > Generate Getters and Setters...】功能自動產生gettersetter方法。但在給這些屬性取名時要注意,private變數的名子和資料表的欄位名沒有直接的關係,但必須和JSP頁面中的標籤的property屬性值一致,如表示輸入產品名稱的文字框,其中property屬性的值就是ProductForm類中的productName變數。如果不一致,將會丟擲異常。其他和ProductForm類的屬性對應的標籤可以檢視上面的程式碼。
   
光有ActionForm類還不夠,還需要在struts-config.xml中的節點中新增如下的內容:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt<form-beans>
     <form-bean name="saveProductForm" type=" mystruts.actionform.ProductForm" />
     <form-bean name="searchProductForm" type="mystruts.actionform.ProductForm" />
form-beans>

    上面的程式碼所配置的兩個ActionForm實際上指的是同一個ProductForm類,但這個ProductForm類在後面要講的兩個動作裡都要使用,為了更容易理解,為這個ProductForm起了兩個不同的別名(saveProductFormsearchProductForm)。
   
下面來實現saveProduct動作的程式碼。Struts Action類必須一般從org.apache.struts.action.Action類繼承。一般在Struts Action類需要覆蓋Action類的execute方法。這個方法有每次客戶端訪問Struts Action時呼叫。我們可以在方法中處理客戶端提交的資料,訪問資料庫等工作。這個方法返回一個ActionForward型別的值,表明在執行完execute後,要forward到的頁面。描述saveProduct動作的類叫SaveProductAction。程式碼如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  package mystruts.action;
  
  
import javax.servlet.http.*;
  
import org.apache.struts.action.*;
  
import mystruts.actionform.*;
  
import mystruts.model.*;
  
  
public class SaveProductAction extends Action
  {
      
// 在客戶端訪問saveProduct動作時執行該方法
      public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          ProductForm saveProductForm 
= (ProductForm) form;
          
try
          {
              Product product 
= new Product(saveProductForm);
              product.save();  
// 儲存產品資訊
              request.setAttribute("info""儲存成功!");   
          }
          
catch (Exception e)
          {
              request.setAttribute(
"info", e.getMessage());
          }
          
return mapping.findForward("save");
      }
  }

    SaveProductAction類中使用了模型類Product驗證並儲存產品資訊。並將操作結果資訊儲存在request的屬性中,key為“info”。在execute的最後,使用了ActionMapping類的findForward方法在struts-config.xml中尋找一個叫“save”的forward。這個forward是一個JSP頁,用於顯示是否將產品資訊儲存成功的資訊。為了可以在struts-config.xml中查詢這個forward,需要在struts-config.xml節點中加入如下的內容。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt<action name="saveProductForm" path="/saveProduct"scope="request" type=" mystruts.action.SaveProductAction">
    <forward name="save" path="/mystruts/save.jsp" />
action>

    從上面的程式碼可以看出,那個用於顯示儲存狀態資訊的JSP頁面叫save.jsp。在工程目錄>"mystruts目錄中建立一個save.jsp檔案,程式碼如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  <%@ page pageEncoding="GBK"%>
  ${requestScope.info}

    IE中輸入如下的URL

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

   
在文字框中輸入相應的資訊後,點“儲存”按鈕,如果輸入的資料是合法的,就會將資料儲存在t_products中, 否則會顯示出錯的原因。    searchProduct動作的實現和saveProduct差不多,也會為三步:實現動作類(SearchProductAction)、在 struts-config.xml中新增配置資訊和實現用於顯示查詢結果的JSP檔案。下面的程式碼分別顯示了這三步所要編寫的程式碼。

SearchProductAction.java

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  package mystruts.action;
  
  
import javax.servlet.http.*;
  
import org.apache.struts.action.*;
  
import mystruts.actionform.*;
  
import mystruts.model.*;
  
import java.util.*;
  
  
public class SearchProductAction extends Action
  {
  
      
public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          ProductForm searchProductForm 
= (ProductForm) form;
          
try
          {
              SearchProduct searchProduct 
= new SearchProduct(searchProductForm);
              List
<String[]> result = searchProduct.search();  // 查詢產品資訊
              if (result.size() > 0)  // 有符合條件的產品資訊
              {
                  request.setAttribute(
"result", result);
                  request.setAttribute(
"info""記錄數:" + String.valueOf(result.size()));
              }
              
else  // 沒有查到任何產品資訊
                  request.setAttribute("info""沒有符合要求的記錄!");
          }
          
catch (Exception e)
          {
              request.setAttribute(
"info", e.getMessage());
          }
          
return mapping.findForward("search");
      }
  }

struts-config.xml中配置searchProduct

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12921506/viewspace-536612/,如需轉載,請註明出處,否則將追究法律責任。

相關文章