隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

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

          本文為原創(chuàng),如需轉(zhuǎn)載,請注明作者和出處,謝謝!
             
             本系列教程將詳細介紹
          Struts 1.x的基本原理和使用方法,讀者可以參閱Struts 2系列教程》來比較Struts 1.xStruts 2.x的相同點和不同點。
             在這篇文章中將以一個簡單的例子
          (mystruts)來演示如何使用MyEclipse來開發(fā)、運行Struts程序,并給出了解決ActionForm出現(xiàn)亂碼問題的方法。讀者可以從本文中了解開發(fā)Struts 1.x程序的基本過程。

          一、本文給出的程序要實現(xiàn)什么功能


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

          1. 接受用戶輸入的產(chǎn)品ID、產(chǎn)品名稱和產(chǎn)品價格。

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

          3. 如果用戶輸入了正確的字段值,程序會將這些字段值保存到數(shù)據(jù)庫中,并顯示“保存成功”信息。

          4. 用戶輸入產(chǎn)品名稱,并根據(jù)產(chǎn)品名稱進行模糊查詢。如果存在符合要求的產(chǎn)品信息。程序會以表格形式顯示這些產(chǎn)品的信息,同時顯示記錄數(shù)。如果未查到任何記錄,會顯示“沒有符合要求的記錄!”信息。

          二、編寫程序前的準(zhǔn)備工作

          1. 建立數(shù)據(jù)庫

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

            # 建立數(shù)據(jù)庫struts
            
          CREATE DATABASE IF NOT EXISTS struts DEFAULT CHARACTER SET GBK;

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

          建立一個支持struts1.xsamples工程

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

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

          (1)將Struts specification改為Struts 1.2。

          (2)Base package for new classes改為struts。

          (3)Default application resources改為struts.ApplicationResources。

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



          圖1

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

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

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

            <?xml version="1.0" encoding="UTF-8"?>
            
          <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.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的配置,代碼如下:

          <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工程已經(jīng)完全支持Struts了。讀者可以看到,如果不使用MyEclipse,那么上面所列出的配置文件的內(nèi)容都必須手工輸入。因此,使用MyEclipse來開發(fā)Struts程序可以省去很多配置xml文件的工作。

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

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

            <%@ page pageEncoding="GBK"%>
            
          <%-- 引用Struts tag--%>
            
          <%@ 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%">
                            
          <%-- 使用Struts tag--%>
                                
          <html:link forward="newProduct">錄入產(chǎn)品信息</html:link>
                            
          </td>
                            
          <td>
                                
          <html:link forward="searchProduct">查詢產(chǎn)品信息</html:link>
                            
          </td>
                        
          </tr>
                    
          </table>
                
          </body>
            
          </html>

              MyEclipse中啟動Tomcat(如果Tomcat處于啟動狀態(tài),在修改完配置文件后,建議在MyEclipseServers頁重新發(fā)布samples工程,以使修改生效)。在IE中輸入如下的URL

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

              我們發(fā)現(xiàn)在輸入上面的URL后,在IE中并未顯示正確的運行結(jié)果,而是拋出了如下的異常:

          java.net.MalformedURLException: Cannot retrieve ActionForward named newProduct

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

            <global-forwards>
                <forward name="newProduct" path="/mystruts/newProduct.jsp" />
                <forward name="searchProduct" path="/mystruts/searchProduct.jsp" />
          </global-forwards>

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



          圖2

              如果想讓index.jsp成為默認的JSP頁面,可以在web.xml中的<welcome-file-list>節(jié)點中加入如下的內(nèi)容:

           <welcome-file>index.jsp</welcome-file>

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

          http://localhost:8080/samples/mystruts

          四、實現(xiàn)添加和查詢產(chǎn)品信息頁面

             
          在本節(jié)中主要實現(xiàn)了用于輸入產(chǎn)品信息(newProduct.jsp)和查詢產(chǎn)品信息(searchProduct.jsp)JSP頁面。

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

            <%@ page pageEncoding="GBK"%>
            
          <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
            
          <html>
                
          <head>
                    
          <title>錄入產(chǎn)品信息</title>
                
          </head>
                
          <body>
                    
          <%-- 向saveProduct動作提交產(chǎn)品信息 --%>
                    
          <html:form action="saveProduct"> 
                        
          <table width="100%">
                            
          <tr>
                                
          <td align="center">
                                    產(chǎn)品編號:
                                    
          <html:text property="productID" maxlength="4" />
                                    
          <p>
                                        產(chǎn)品名稱:
                                        
          <html:text property="productName" />
                                    
          <p>
            
                                        產(chǎn)品價格:
                                        
          <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中只提供了一個文本框用于對產(chǎn)品名稱進行模糊查詢。在<samples工程目錄>" mystruts目錄中建立一個searchProduct.jsp文件,代碼如下:

            <%@ page pageEncoding="GBK"%>
            
          <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
            
          <html>
                
          <head>
                    
          <title>查詢產(chǎn)品信息</title>
                
          </head>
                
          <body>
                    
          <%--  向searchProduct動作提交查詢請求 --%>
                    
          <html:form action="searchProduct">
                        
          <table width="100%">
                            
          <tr>
                                
          <td align="center">
                                    產(chǎn)品名稱:
                                    
          <html:text property="productName" />
                                
          </td>
                            
          </tr>
                            
          <tr>
                                
          <td align="center">
                                    
          <br>
                                    
          <html:submit value=" 查詢 " />
                                
          </td>
                            
          </tr>
                        
          </table>
                    
          </html:form>
                
          </body>
            
          </html>

              現(xiàn)在啟動Tomcat,并使用如下兩個URL來訪問newProduct.jspsearchProduct.jsp

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

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


          五、通過模型類操作數(shù)據(jù)庫

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

          配置連接池(用于連接數(shù)據(jù)庫struts

            <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"/>

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

             由于ProductSearchProduct都需要使用數(shù)據(jù)庫連接池來連接數(shù)據(jù)庫,因此,可以將連接數(shù)據(jù)庫的工作提出來作為一個父類(Struts)提供,代碼如下:

          package 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();  // 從數(shù)據(jù)庫連接池獲得一個Connection
              }
          }

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

            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();
                }
                
          // 驗證客戶端提交的數(shù)據(jù)
                public void validate() throws Exception
                {
                    
          if (form.getProductID().trim().equals(""))
                        
          throw new Exception("產(chǎn)品ID不能為空!");
                    
          if(form.getProductID().length() > 4)
                        
          throw new Exception("產(chǎn)品ID最長為4位!");
                    
          if (form.getProductName().trim().equals(""))
                        
          throw new Exception("產(chǎn)品名稱不能為空");
                    
          if (Float.compare(form.getPrice(), 0<= 0)
                        
          throw new Exception("產(chǎn)品價格必須大于0");
                }
                
          // 將客戶端提交的產(chǎn)品信息保存到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();   
          // 執(zhí)行INSERT語句
                        pstmt.close();
                        conn.close();
                    }
                    
          catch (Exception e)
                    {
                        
          throw new Exception(e.getMessage());
                    }
                }
            }

              Product類中使用了一個ProductForm類,這個類是一個ActionForm類,它的功能是保存客戶端提交的數(shù)據(jù)。關(guān)于這個類將在下面詳細介紹。Product類通過構(gòu)造方法的form參數(shù)將客戶端提交的數(shù)據(jù)傳入Product類的對象實例中,并在構(gòu)造方法中驗證這些數(shù)據(jù),如果發(fā)現(xiàn)數(shù)據(jù)不合法,就會拋出一個異常。當(dāng)客戶端提交的數(shù)據(jù)合法后,成功建立了一個Product類的對象實例,然后可以通過簡單地調(diào)用save方法將數(shù)據(jù)保存到t_products表中。

              Product類似,在<samples工程目錄>"src目錄中建立一個SearchProduct.java文件,代碼如下:

            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;
                }    
                
          // 查詢產(chǎn)品信息,并通過List返回查詢結(jié)果
                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();  // 開始執(zhí)行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對象實例中的數(shù)據(jù),而只是將ProductForm對象作為傳遞查詢請求信息(實際上只需要產(chǎn)品名稱)的工具而已。

          六、實現(xiàn)控制器

             
          在這一節(jié)要實現(xiàn)的控制器是基于StrutsWeb程序的核心部分之一:控制器實質(zhì)上也是普通的Java類,但這個Java類一般要從org.apache.struts.action.Action類繼承。控制器的主要功能是接受并處理從JSP頁面提交的數(shù)據(jù)、通過模型(Model)和數(shù)據(jù)庫交互以及forward到相應(yīng)的頁面(可以是任何頁面,如html、JSP和Servlet等)。在實現(xiàn)控制器之前,需要先實現(xiàn)一個ActionForm類, 這個類的作用是保存JSP頁面提交的數(shù)據(jù)。在<samples工程目錄>"src目錄中建立一個ProductForm.java文件,代碼如下:

            package mystruts.actionform;
            
            
          import org.apache.struts.action.*;
            
            
          public class ProductForm extends ActionForm
            {
                
          private String productID;  // 產(chǎn)品ID
                private String productName; // 產(chǎn)品名稱
                private float price;  // 產(chǎn)品價格
                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類繼承,而且在類中需要按著需要保存的數(shù)據(jù)表字段添加屬性。如產(chǎn)品ID的屬性是productName。在MyEclipse中可以只定義三個private變量,然后使用MyEclipse的Source > Generate Getters and Setters...】功能自動產(chǎn)生gettersetter方法。但在給這些屬性取名時要注意,private變量的名子和數(shù)據(jù)表的字段名沒有直接的關(guān)系,但必須和JSP頁面中的<html>標(biāo)簽的property屬性值一致,如<html:text property="productName" />表示輸入產(chǎn)品名稱的文本框,其中property屬性的值就是ProductForm類中的productName變量。如果不一致,將會拋出異常。其他和ProductForm類的屬性對應(yīng)的<html>標(biāo)簽可以查看上面的代碼。
             
          光有ActionForm類還不夠,還需要在struts-config.xml中的<struts-config>節(jié)點中添加如下的內(nèi)容:

          <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)。
             
          下面來實現(xiàn)saveProduct動作的代碼。Struts Action類必須一般從org.apache.struts.action.Action類繼承。一般在Struts Action類需要覆蓋Action類的execute方法。這個方法有每次客戶端訪問Struts Action時調(diào)用。我們可以在方法中處理客戶端提交的數(shù)據(jù),訪問數(shù)據(jù)庫等工作。這個方法返回一個ActionForward類型的值,表明在執(zhí)行完execute后,要forward到的頁面。描述saveProduct動作的類叫SaveProductAction。代碼如下:

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

              SaveProductAction類中使用了模型類Product驗證并保存產(chǎn)品信息。并將操作結(jié)果信息保存在request的屬性中,key為“info”。在execute的最后,使用了ActionMapping類的findForward方法在struts-config.xml中尋找一個叫“save”的forward。這個forward是一個JSP頁,用于顯示是否將產(chǎn)品信息保存成功的信息。為了可以在struts-config.xml中查找這個forward,需要在struts-config.xml<action-mappings>節(jié)點中加入如下的內(nèi)容。

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

              從上面的代碼可以看出,那個用于顯示保存狀態(tài)信息的JSP頁面叫save.jsp。在<samples工程目錄>"mystruts目錄中建立一個save.jsp文件,代碼如下:

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

              IE中輸入如下的URL

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

             
          在文本框中輸入相應(yīng)的信息后,點“保存”按鈕,如果輸入的數(shù)據(jù)是合法的,就會將數(shù)據(jù)保存在t_products中,否則會顯示出錯的原因。    searchProduct動作的實現(xiàn)和saveProduct差不多,也會為三步:實現(xiàn)動作類(SearchProductAction)、在struts-config.xml中添加配置信息和實現(xiàn)用于顯示查詢結(jié)果的JSP文件。下面的代碼分別顯示了這三步所要編寫的代碼。

          SearchProductAction.java

            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();  // 查詢產(chǎn)品信息
                        if (result.size() > 0)  // 有符合條件的產(chǎn)品信息
                        {
                            request.setAttribute(
          "result", result);
                            request.setAttribute(
          "info""記錄數(shù):" + String.valueOf(result.size()));
                        }
                        
          else  // 沒有查到任何產(chǎn)品信息
                            request.setAttribute("info""沒有符合要求的記錄!");
                    }
                    
          catch (Exception e)
                    {
                        request.setAttribute(
          "info", e.getMessage());
                    }
                    
          return mapping.findForward("search");
                }
            }

          struts-config.xml中配置searchProduct動作

          <action name="searchProductForm" path="/searchProduct" scope="request" type="mystruts.action.SearchProductAction">
              <forward name="search" path="/mystruts/search.jsp" />
          </action>

          search.jsp

            <%@ page pageEncoding="GBK"%>
            
          <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
            
          <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
            
          <html>
                
          <body>
          <%-- 從request的result中取出查詢結(jié)果 --%>
                    
          <c:set var="result" value="${requestScope.result}" />
                    
          <table width="100%">
                        
          <tr align="center">
                            
          <td>
                                ${requestScope.info}
                            
          </td>
                        
          </tr>
                        
          <tr align="center">
                            
          <td>
                                
          <logic:present name="result">
                                    
          <table border="1">
                                        
          <tr align="center">
                                            
          <td> 產(chǎn)品ID </td>
                                            
          <td> 產(chǎn)品名稱 </td>
                                            
          <td> 價格 </td>
                                        
          </tr>
                                        
          <logic:iterate id="row" name="result">
                                            
          <tr> <td> ${row[0]} </td>
                                                
          <td> ${row[1]} </td>
                                                
          <td> ${row[2]} </td>
                                            
          </tr>
                                        
          </logic:iterate>
                                    
          </table>
                                
          </logic:present>
                            
          </td>
                        
          </tr>
                    
          </table>
                
          </body>
            
          </html>

              IE中輸入如下的URL

              http://localhost:8080/samples/%20mystruts/searchProduct.jsp

             
          在“產(chǎn)品名稱”文本框中輸入產(chǎn)品名稱的一部分,程序就會查詢出所有包含輸入的產(chǎn)品名稱的產(chǎn)品信息,并將結(jié)果顯示出來。

          七、解決ActionForm的亂碼問題

           

              到現(xiàn)在為止,程序的功能部分已經(jīng)全部實現(xiàn)完了。但還存在一個問題。當(dāng)我們在產(chǎn)品名稱中輸入中文時,雖然將客戶端提交的數(shù)據(jù)成功保存到數(shù)據(jù)庫中,但是在t_products表中的product_name字段顯示的都是亂碼。產(chǎn)生這個問題的原因只有一個,就是客戶端提交的數(shù)據(jù)的編碼格式和數(shù)據(jù)庫的編碼格式不一致造成的。當(dāng)然,解決這個問題的方法有很多,但筆者認為最容易的就是使用過濾器。所謂過濾器,就是在客戶端提交數(shù)據(jù)后,在交由服務(wù)端處理之前所執(zhí)行的一段服務(wù)端代碼(一般為Java代碼)。一個過濾器是一個實現(xiàn)javax.servlet.Filter接口的類。在本例中要使用的過濾器類叫EncodingFilter,實現(xiàn)代碼如下:

          EncodingFilter.java


            package filter;
            
          import java.io.IOException;
            
          import javax.servlet.*;
            
          public class EncodingFilter implements Filter
            {
                
          public void destroy() {  }
                
          public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain) 
          throws IOException, ServletException
                {
                    request.setCharacterEncoding(
          "GBK");  // 將客戶端提交的數(shù)據(jù)設(shè)為GBK編碼格式
                    // 繼續(xù)處理客戶端提交的數(shù)據(jù),如果不寫這條語句,Servlet引擎將不會處理所過濾的頁面
                    chain.doFilter(request, response);      
                }
                
          public void init(FilterConfig filterConfig) throws ServletException {   }  
            }

              Filter接口的doFilter方法是過濾器的核心方法。其中FilterChain類的doFilter方法允許繼續(xù)處理客戶端提交的數(shù)據(jù)。我們還可以使用這個方法來臨時關(guān)閉Web站點的某個或全部的頁面(根據(jù)過濾器的設(shè)置而定)。由于本書的數(shù)據(jù)庫使用的是GBK編碼格式,因此,需要使用ServletRequestsetCharacterEncoding方法將客戶端提交的數(shù)據(jù)也設(shè)為GBK編碼格式。

              除了實現(xiàn)過濾器類,我們還需要在web.xml中的<web-app>節(jié)點加入如下的配置信息才能使過濾器生效:

          web.xml中配置過濾器


          <filter>
              <filter-name>EncodingFilter</filter-name>
              <filter-class>
                  filter.EncodingFilter
              </filter-class>
          </filter>
          <filter-mapping>
              <filter-name>EncodingFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>

              在重新啟動Tomcat后,重新輸入一條帶中文的產(chǎn)品信息,看看是否可以將中文保存在數(shù)據(jù)庫中?

          下一篇:
          Struts1.x系列教程(2):簡單的數(shù)據(jù)驗證




          Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-01-13 12:17 銀河使者 閱讀(42062) 評論(36)  編輯  收藏 所屬分類: java 、web 原創(chuàng)struts1.x

          評論

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          不是打擊你,倒退6、7年,你寫的真是好文章。
          2009-01-15 21:27 | 看看日歷

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          這系列文章就是幾年前寫的,做個總結(jié),不過一直沒發(fā)出來,現(xiàn)在發(fā)出來,如果讀者已經(jīng)覺得這些已經(jīng)會了或已經(jīng)過時了,可以略過此文,看我寫的《Struts 2系列文章》或其他的文章,當(dāng)然,也可以什么都不看,打打醬油也可,哈哈!
          2009-01-16 08:41 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          感謝樓主。
          2009-01-21 15:15 | hunk

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          新人是不是應(yīng)該要從struts1.0學(xué)起啊
          2009-02-17 11:12 | java

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @java
          學(xué)哪個版本可由個人自己決定,現(xiàn)在有很多公司還有使用Struts1.x,當(dāng)然,也可以從Struts 2.x開始學(xué)。關(guān)于Struts2.x,可以參閱我寫的Struts2.x教程:http://www.aygfsteel.com/nokiaguy/archive/2009/nokiaguy/archive/2009/nokiaguy/archive/2008/04/15/193229.html
          2009-02-17 11:32 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          【在<samples工程目錄>中建立一個mystruts目錄,然后在<samples工程目錄>" mystruts目錄中建立一個index.jsp文件】
          應(yīng)改為:
          【在<webroot>下建立一個mystruts目錄,然后在mystruts目錄下建立一個index.jsp文件】
          【struts-config.xml文件中<struts-config>節(jié)點中添加兩個全局的forward,代碼如下:
          <global-forwards>
          <forward name="newProduct" path="/mystruts/newProduct.jsp" />
          <forward name="searchProduct" path="/mystruts/searchProduct.jsp" />
          </global-forwards>】
          應(yīng)改為:

          <forward name="newProduct" path="/mystruts/newProduct.jsp">
          </forward>
          <forward name="searchProduct" path="/mystruts/searchProduct.jsp">
          </forward>


          2009-02-18 22:46 | zhy

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @zhy
          是的,也可以是web根目錄。

          <forward name="newProduct" path="/mystruts/newProduct.jsp" /> 這么不行嗎,<forward>沒有子元素。這么也可以的。這是xml的寫法,與struts沒關(guān)系。
          2009-02-18 23:05 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          List<String[]> result=new LinkedList<String[]>();為什么我這句會報錯啊
          錯誤如下:LinkedList cannot be resolved to a type
          2009-02-24 16:19 | test

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @test
          原因是你沒引用LinkedList,在程序前面加上import java.util.*;

          2009-02-24 16:34 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          有啊,import java.util.*我有引用進來啊
          2009-02-24 21:36 | test

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @test
          你是用myeclipse開發(fā)的嗎?那不太可能,struts1.x是否可成功發(fā)布?
          2009-02-25 08:36 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          問題解決了 是我大意只引進了list
          謝謝??!
          2009-02-25 09:04 | test

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          博主救命啊 按你的做出現(xiàn)情況了^_^
          type Exception report

          message

          description The server encountered an internal error () that prevented it from fulfilling this request.

          exception

          javax.servlet.ServletException: Exception creating bean of class mystruts.actionform.ProductForm: {1}
          org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:848)
          org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:781)
          org.apache.jsp.newProduct_jsp._jspService(org.apache.jsp.newProduct_jsp:82)
          org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
          org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:322)
          org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
          org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)


          root cause

          javax.servlet.jsp.JspException: Exception creating bean of class mystruts.actionform.ProductForm: {1}
          org.apache.struts.taglib.html.FormTag.initFormBean(FormTag.java:487)
          org.apache.struts.taglib.html.FormTag.doStartTag(FormTag.java:457)
          org.apache.jsp.newProduct_jsp._jspx_meth_html_form_0(org.apache.jsp.newProduct_jsp:98)
          org.apache.jsp.newProduct_jsp._jspService(org.apache.jsp.newProduct_jsp:71)
          org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
          org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:322)
          org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
          org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)


          note The full stack trace of the root cause is available in the Apache Tomcat/5.5.9 logs.

          2009-02-26 21:45 | aaa

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @aaa
          你這異常是建立mystruts.actionform.ProductForm錯誤,你將ProductForm類放在哪了?
          2009-02-26 22:25 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          路徑是這樣的src/mystruts/actionform/ProductForm.java
          應(yīng)該是對的啊
          2009-02-27 10:01 | aaa

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          @看看日歷
          呵呵,應(yīng)該是幾年前的文章了,類與類之間的耦合性太緊湊了!沒有bean的設(shè)計理念,一般的bean去繼承dao,呵呵!
          還好,至少我從上到下還有興趣看下來,還能看懂!
          2009-02-27 14:46 | 葛坤進

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @葛坤進
          DAO?這篇文章只是演示如何使用Struts1.x,還沒上升到層次的概念。一個Helloworld是不需要使用任何設(shè)計模式的,那與本文的主旨不符。否則就成唯模式論了!
          但愿本文能給想學(xué)習(xí)struts1.x的朋友帶來收獲!_^_
          2009-02-27 15:05 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          鄙視“2009-01-15 21:27 看看日歷 ”

          ------
          支持樓主分享這么好的文章,作為初學(xué)者很需要,如果你覺得文章或技術(shù)老化,您可以去美國硅谷工作,或者發(fā)表您的博士論文,不要在這里當(dāng)專家。
          2009-03-30 11:32 | 鄙視第一個留言的家伙

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          學(xué)習(xí)中,
          2009-07-07 11:06 | ziyoo0830

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          文章不錯,挺好。可是 樓主 我完全按照你寫的去做的,怎么查詢好用,增加不好用,產(chǎn)品信息填完后,一提交就出錯,說什么“The requested resource (/samples/mystrut/saveProduct) is not available.”,還有上面有個類叫product,是不是應(yīng)該是newproduct啊,我找樂好長時間的錯誤了,希望得到樓主的幫助,萬分感激,如果方便的話,QQ最好。我QQ 442187735
          2009-07-08 13:44 | sun。java

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          這個錯誤是沒找到saveProduct這個動作的原因,看看你的struts-config.xml的配置?;虬堰@個文件的內(nèi)容貼上來。
          2009-07-08 15:53 | 銀河使者

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          <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"/>
          <Resource/>中間name=“jdbc/mysql";同時少了global="jdbc/mysql";
          2009-08-08 18:53 | weiwei

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          外星人算不算‘這個世界’上的。。。???
          2010-04-13 15:54 | 火星華人

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          按照你的方法做 一直出現(xiàn)如下問題 為什么啊 求助??
          type Exception report

          message

          description The server encountered an internal error () that prevented it from fulfilling this request.

          exception

          org.apache.jasper.JasperException: /mystruts/index.jsp(2,4) Invalid directive
          org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
          org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
          org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:88)
          org.apache.jasper.compiler.Parser.parseDirective(Parser.java:473)
          org.apache.jasper.compiler.Parser.parseFileDirectives(Parser.java:1749)
          org.apache.jasper.compiler.Parser.parse(Parser.java:127)
          org.apache.jasper.compiler.ParserController.doParse(ParserController.java:255)
          org.apache.jasper.compiler.ParserController.parseDirectives(ParserController.java:120)
          org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:180)
          org.apache.jasper.compiler.Compiler.compile(Compiler.java:354)
          org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)
          org.apache.jasper.compiler.Compiler.compile(Compiler.java:321)
          org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)
          org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
          org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
          org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:717)


          note The full stack trace of the root cause is available in the Apache Tomcat/6.0.33 logs.

          2012-03-13 16:20 | cc

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          為什么是數(shù)據(jù)庫的問題呢?提示:
          Name jdbc is not bound in this Context
          這是什么問題呢?
          2012-04-13 11:10 | 小晨

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          有沒有 做好pdf 或是打包好的 離線文檔 若是有 希望樓主好人能發(fā)給我 1、2的都有最好 沒有也可是1的 謝謝樓主 qianlixuesha@163.com
          2012-08-24 08:46 | 南宮凌天

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          @aaa

          原因找到了。
          <form-beans>
          <form-bean name="saveProductForm" type=" mystruts.actionform.ProductForm" />
          <form-bean name="searchProductForm" type="mystruts.actionform.ProductForm" />
          </form-beans>

          上面這段,第一個type="后面有一個空格。
          2013-01-31 23:47 | bbb

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          博主,你寫得還蠻好的。最近分到一個項目組用的struts1,看你的文章明白了一些。
          2013-07-03 15:41 | 空心稻草人

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序[未登錄]  回復(fù)  更多評論   

          PreparedStatement pstmt = conn.prepareStatement(sql);報錯
          2013-07-04 16:42 | 111

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          有沒有誰做好的!給打個包發(fā)到我qq里!我qq312896286
          2013-08-24 13:20 | [zhzhyo

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          感謝樓主分享這么好的東西,雖然說現(xiàn)在都是 struts 2 ,但是struts 1 還是經(jīng)典啊,對于我們這些初學(xué)者來說,還是很有幫助的
          2013-09-09 21:08 | 涂涂

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          dfddffd
          2013-11-20 23:03 | xc

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          誰有弄好的麻煩給我發(fā)一個謝謝395020276@qq.com
          2013-12-06 10:26 | 李雙賀

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          這個問題你是怎么解決的?
          @aaa
          2014-05-28 21:49 | 樊鳳鮮

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          原因找到了。
          <form-beans>
          <form-bean name="saveProductForm" type=" mystruts.actionform.ProductForm" />
          <form-bean name="searchProductForm" type="mystruts.actionform.ProductForm" />
          </form-beans>

          上面這段,第一個type="后面有一個空格。

          查了一個小時
          2014-09-03 15:35 | zora

          # re: Struts1.x系列教程(1):用MyEclipse開發(fā)第一個Struts程序  回復(fù)  更多評論   

          博主, 是我沒理解還是你的各個層 寫的有問題。 感覺好混亂
          2015-09-06 09:59 | aiyou
          主站蜘蛛池模板: 怀仁县| 舞钢市| 内丘县| 卢氏县| 新密市| 榆社县| 乌拉特中旗| 深水埗区| 四川省| 柳江县| 佛冈县| 贵定县| 田东县| 宁国市| 济宁市| 清原| 新郑市| 襄垣县| 汶川县| 开封县| 循化| 囊谦县| 友谊县| 广西| 永州市| 嘉义市| 金华市| 德格县| 台北市| 和田县| 托克托县| 霞浦县| 商城县| 安宁市| 边坝县| 普宁市| 武胜县| 大渡口区| 璧山县| 巫溪县| 义马市|