從零開始創建基於struts1.2 + Hibernate3.0 Web工程

1. 環境說明

  安裝Eclipse和安裝MyEclipse組件的過程在這裏不進行介紹。可以參考其它資料完成Eclipse環境的安裝與資源的配置。

  接下來的篇幅將給出一個在MyEclipse開發環境下的一個Web工程實例。說明在MyEclipse的集成開發環境下,如何利用Struts進行Web工程開發。

例子工程的環境:

Windows 2000 Professional或者更高的版本。
J2SDK 5.0
Apache Tomcat 5.0
MySQL 4.0.14b
Eclipse-SDK-3.1
MyEclipse 4.0
SQLyog407(
可選)

2. 例子工程說明

  本例子是利用struts架構,實現用戶logonWeb工程。在這個工程中,用戶可以訪問三個頁面,index.jsplogon.jspmenu.jsp。他們的關係如下圖所示:

  其中,左上角的方框代表struts結構中/WEB-INF/struts-config.xml中定義的,<global-forwards>,也就是在整個Web工程中,只要有logon的動作發生,都會使畫面轉移到logon.jsp。那麼處理logon.jsp畫面的formbeen是上圖上放右側的模塊表示的formbean來完成——logonForm

  LogonFrom處理後會有兩個結果,“success”的時候,畫面會轉移到menu.jsp,失敗的話,回到logon畫面。

  在logon畫面,用戶需要輸入用戶名和密碼,點擊submit,進行登錄認證。輸入內容的檢測是在logonFormbean中檢查。判斷操作在logonActionbean中完成,在logonActionbean中,需要訪問MySql數據庫的Account表格,進行用戶和密碼的查詢。查詢成功的話,證明用戶認證通過。

3. 建立工程

3.1 v創建新的Web Project

  啓動MyEclipse,通過Wizard,建立一個Web工程。如下圖:

  點擊project後,MyEclipse彈出工程的對話框,我們在所羅列的工程中選中MyEclipse下面的J2EE ProjectsWeb Project。如下圖所示:

  在Wizard的下一頁,必要的輸入信息是Project NameContext root URL。最後點擊finish,一個空的WebProject就已經建立起來了

3.2 加載Struts

  在新創建的Web Project中加載struts

  在MyEclipse集成開發環境下,已經集成了struts開發的環境,用戶可以根據自己的實際需要,加載struts的環境。加載過程如下圖:

  右鍵點擊剛剛創建好的工程,點擊MyEclipse屬性,在擴展的右鍵菜單裏面,選擇Add Struts Capabilities

  MyEclipse集成環境就會自動將Struts所需要的目錄結構進行創建,並將需要的環境資源自動引用到相應的目錄中去。

  我們還要對自動生成的Struts進行修正,首先,修改WEB-INF/web.xml <web-app>標籤中的屬性刪除。<web-app XXXXXXXXXXXXXXX> -> <web-app>

  其次要添加本工程的標籤定義庫,添加<taglib></taglib>

<taglib>

    <taglib-uri>/WEB-INF/app.tld</taglib-uri>

    <taglib-location>/WEB-INF/app.tld</taglib-location>

  </taglib>

  <taglib>

    <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>

    <taglib-location>/WEB-INF/struts-bean.tld
</taglib-location>

  </taglib>

  <taglib>

    <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>

    <taglib-location>/WEB-INF/struts-html.tld
</taglib-location>

  </taglib>

  <taglib>

    <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>

    <taglib-location>/WEB-INF/struts-logic.tld
</taglib-location>

  </taglib>

4. 完善工程

4.1 添加index畫面

  在加載完Struts結構之後,就可以在這個工程中添加內容了。我們可以添加一個畫面JSP。添加JSP很簡單,點擊工程的右鍵,添加JSPWizard會彈出一個添加的對話框。如下圖:

  在File Name欄中改變文件名稱,改成index.jsp把這個jsp作爲Web工程的第一個畫面。

  Template To Use 欄可以選擇第五項(選擇選擇其他項也可以)。

  對於新生成的jsp文件進行必要的修改。

Index.jsp文件:

<taglib>

<%@ page language="java" pageEncoding="UTF-8"%>

 

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <title>My JSP 'index.jsp' starting page</title>

   

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">

    <meta http-equiv="keywords" content="
keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

   

    <!--

    <link rel="stylesheet" type="text/css" href="styles.css">

    -->

  </head>

 

  <body>

  <h3><bean:message key="index.heading"/></h3>

        <html:link page="/logon.jsp"><bean:message key="index.logon"/></html:link>

</body>

</html>

 其中藍色和橙色部分是修改的內容,藍色部分是今後自動添加jsp文件必須修改的地方,讓這個頁面用到的tag都能在這個工程中定義的tag集合中找到。

  橙色部分是畫面的主要顯示內容。<h3></h3>的內容是一段文本,內容被struts結構的靜態文本集合中的index.heading給替換掉了。這個文本的內容可以在工程的src/com/yourcompany/struts/ApplicationResources.properties文件中找到。Struts結構推薦用戶將頁面上的靜態文本用ApplicationResources的形式替換。這樣可以在大量的維護頁面文字時候,感到便捷很多,同時,也大大減輕了多國語言版本網頁的維護。

  <html:link page="/logon.jsp">相當於html語言中的<a herf=xxxxx>。這個tag是在/WEB-INF/struts-html.tld中可以找到並在顯示頁面的時候,被轉義成<a herf=xxxxx>

4.2 添加logon畫面

  添加方法跟添加index畫面相同。修改內容稍微有些差別。

Logon.jsp的內容:

<taglib>

<%@ page language="java" pageEncoding="UTF-8"%>

 

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html:html locale="true">

  <head>

    <html:base />

   

    <title>logon.jsp</title>

   

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">   

    <meta http-equiv="keywords"
content="keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

  </head>

 

  <body>

    <html:form action="/logon.do" method="post"  focus="userName">

      <table border="0">

        <tr>

          <td><bean:message key="prompt.username"/></td>

          <td><html:text property="userName" /></td>

        </tr>

        <tr>

          <td>Password:</td>

          <td><html:password property="password" /></td>

        </tr>

        <tr>

          <td colspan="2" align="center"><html:submit /></td>

        </tr>

      </table>

    </html:form>

  </body>

</html:html>

  其中,藍色部分是引用本工程的tag標示庫,紅色的部分是表單屬性名稱的修改,和指定action動作的名稱。

4.3 修改WEB-INF/struts-config.xml

  畫面上出現了form,那麼根據struts的結構要求,就必須在WEB-INF/struts-config.xml中明確這個formformbean(表單內容校驗的java class)是什麼。執行這個formaction(表單執行的內部邏輯)是什麼,以及action的結果會產生怎樣的畫面遷移。這些都是在WEB-INF/struts-config.xml中定義的。也就是標準的MVC架構所要求的。

<taglib>

<struts-config>

  <form-beans >

    <form-bean name="logonForm" type="com.yourcompany.forms.
LogonForm" />

  </form-beans>

 

  <global-forwards >

    <forward name="logon" path="/logon.jsp" />

  </global-forwards>

 

  <action-mappings >

    <action

      path="/logon"

      type="com.yourcompany.actions.LogonAction"

      name="logonForm"

      scope="request"

      input="/logon.jsp">

      <forward name="success" path="/menu.jsp" />

      <forward name="fails" path="/logon.jsp" />

    </action>

  </action-mappings>

 

  <message-resources parameter="com.yourcompany.struts.
ApplicationResources" />

</struts-config>

 

  其中<action>部分是說明action的屬性。

  Path 指定Action處理的URL

  Type 指定Action的類名

  Name 指定Action主力的ActionForm名,與<form-beans >元素的name屬性匹配。

  Scope 指定ActionForm存在的範圍

  Input 指定包含客戶提交表單的網頁,如果ActionFormValidate方法返回錯誤,則因該把用戶請求轉發到這個網頁。

  Validate 如果取值爲true,則表示ActionServlet應該調用ActionFormvalidate方法

  Forward 就是Actionexecute方法執行完畢後,把客戶請求在轉發給相應的頁面。

4.4 添加formbeanactionbean

  添加方法跟JSP相同,但是在選擇superclass的時候,formbean要選擇ActionForm作爲類的父類。Actionbean的父類是Action

  下面是各自的代碼

LogonForm.java文件內容:

<taglib>

package com.yourcompany.forms;

import javax.servlet.http.HttpServletRequest;

 

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionMapping;

 

public class LogonForm extends ActionForm {

 

        private static final long serialVersionUID
= 7322786881443789688L;

        // ------------------------------
--------------------------- Instance Variables

    private String username = null;

    private String password = null;

 

        // -------------------------
-------------------------------- Methods

    public String getUserName() {

               return (this.username);

    }

 

    public void setUserName(String username) {

        this.username = username;

    }

 

    public String getPassword() {

               return (this.password);

    }

 

    public void setPassword(String password) {

        this.password = password;

    }

 

        public void reset(ActionMapping mapping,
HttpServletRequest request) {

               this.password = null;

               this.username = null;

        }

 

}

 

LogonAction.java文件:

package com.yourcompany.actions;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

 

import com.yourcompany.forms.LogonForm;

 

public class LogonAction extends Action {

 

        public ActionForward execute(ActionMapping
mapping, ActionForm form,

                       HttpServletRequest request,
HttpServletResponse response) {

 

               String userName = null;

               String password = null;

 

               if (form != null) {

                       userName = ((LogonForm) form).getUserName();

                       password = ((LogonForm) form).getPassword();

               }

               if(userName.equals(“test1”) && password.
equals(“test1”)){

                       return (mapping.findForward("success"));

}

else{

        return (mapping.findForward("fails"));

}

        }

 

}

 

4.5 添加menu畫面

  與添加index畫面的方法相同。下面是menu.jsp文件的內容

<taglib>

<%@ page language="java" pageEncoding="UTF-8"%>

 

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html:html locale="true">

  <head>

    <html:base />

        <title>menu.jsp</title>

        <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">   

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

  </head>

    <body>

          <h3><bean:message key="menu.message"/></h3>

  </body>

</html:html>

 

5. 調試工程

如果本地機器已經安裝了Tomcat5,那麼可以在MyEclilpse的環境下調試工程了。

指定Tomcat5 web application service 如下圖:

Enable選項打開,並且指定Tomcat的安裝目錄。

配置目前的工程到Tomcat中去。

點選工具欄上的被紅線圈出的按鈕

在彈出來的對話框中選擇,我們創建的工程,和添加Tomcat5 web application service

然後就可以按下工具欄上的啓動服務按鈕,調試這個Web工程了。

每一次改動工程中的文件後,要想看看改動後的效果,那麼就在配置工程中,重新發布這個工程到tomecat5去。

6. Tomcat下如何配置mysql的數據庫連接池

6.1 配置server.xml

配置Tomcatserver.xml文件,路徑:【TOMCAT_HOME/common/lib下的server.xml文件在</host>之前加入以下內容以添加JNDI數據源:

<taglib>

<Context path="/DBTest" docBase="DBTest"

        debug="5" reloadable="true" crossContext="true">

  <Logger className="org.apache.catalina.logger.FileLogger"

             prefix="localhost_DBTest_log." suffix=".txt"

             timestamp="true"/>

  <Resource name="jdbc/TestDB"

               auth="Container"

               type="javax.sql.DataSource"/>

  <ResourceParams name="jdbc/TestDB">

    <parameter>

      <name>factory</name>

    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

    </parameter>

    <!-- Maximum number of dB connections in pool. Make sure you

         configure your mysqld max_connections large enough to handle

         all of your db connections. Set to 0 for no limit.

         -->

    <parameter>

      <name>maxActive</name>

      <value>100</value>

    </parameter>

    <!-- Maximum number of idle dB connections to retain in pool.

         Set to 0 for no limit.

         -->

    <parameter>

      <name>maxIdle</name>

      <value>30</value>

    </parameter>

    <!-- Maximum time to wait for a dB connection to become available

         in ms, in this example 10 seconds. An Exception is thrown if

         this timeout is exceeded.  Set to -1 to wait indefinitely.

         -->

    <parameter>

      <name>maxWait</name>

      <value>10000</value>

    </parameter>

    <!-- MySQL dB username and password for dB connections  -->

    <parameter>

     <name>username</name>

     <value>root</value>

    </parameter>

    <parameter>

     <name>password</name>

     <value> </value>

    </parameter>

    <!-- Class name for mm.mysql JDBC driver -->

    <parameter>

       <name>driverClassName</name>

       <value>org.gjt.mm.mysql.Driver</value>

    </parameter>

    <!-- The JDBC connection url for connecting to your MySQL dB.

         The autoReconnect=true argument to the url makes sure that the

         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the

         connection.  mysqld by default closes idle connections after 8 hours.

         -->

    <parameter>

      <name>url</name> <value>jdbc:mysql://192.168.0.208:3306
/db_test_account?autoReconnect=true</value>

    </parameter>

  </ResourceParams>

</Context>

注意:

*其中藍色字體表示你這個應用的路徑和別名,也就是你訪問自己配置的這個web站點的名字,注意區分大小寫,必須一致,否則系統無法正常運行(:http://localhost:8080/DBTest)

*其中紅色字體表示數據源的名字,注意將會被web.xml和你訪問數據庫的程序調用

6.2 配置web.xml

配置Web用程序的web.xml文件

<taglib>

<?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE web-app PUBLIC

    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

  <description>MySQL Test App</description>

  <resource-ref>

      <description>DB Connection</description>

      <res-ref-name>jdbc/TestDB</res-ref-name>

      <res-type>javax.sql.DataSource</res-type>

      <res-auth>Container</res-auth>

  </resource-ref>

</web-app>

6.3 訪問數據庫的程序片段

<taglib>

package swt.db.DBUtility;

 

import javax.naming.*;

import javax.sql.*;

import java.sql.*;

 

public class DBTest {

 

  String foo = "Not Connected";

  int bar = -1;

    

  public void init() {

    try{

      Context ctx = new InitialContext();

      if(ctx == null ) 

          throw new Exception("Boom - No Context");

      DataSource ds = 

            (DataSource)ctx.lookup(

               "java:comp/env/jdbc/TestDB");

      if (ds != null) {

        Connection conn = ds.getConnection();     

        if(conn != null)  {

            foo = "Got Connection "+conn.toString();

            Statement stmt = conn.createStatement();

            ResultSet rst = 

                stmt.executeQuery(

                  " select UserName from t_account ");

            if(rst.next()) {

               foo=rst.getString(1);

               bar=208;

            }

            conn.close();

        }

      }

    }catch(Exception e) {

      e.printStackTrace();

    }

 }

 public String getFoo() { return foo; }

 public int getBar() { return bar;}

}

6.4 Jsp頁面(index.jsp)

<taglib>

<%@ page language="java" pageEncoding="UTF-8"%>

<%@ page import ="swt.db.DBUtility.*" %>

<html>

  <head>

    <title>DB Test</title>

  </head>

  <body>

  <%

    DBTest tst = new DBTest();

    tst.init();

  %>

  <h2>Results</h2>

    Foo <%= tst.getFoo() %><br>

    Bar <%= tst.getBar() %>

  </body>

</html>

啓動Tomcat在瀏覽器上輸入http://localhost:8080/DBTest

備註:

連接池配置(Database Connection Pool (DBCP) Configurations)
DBCP
使用的是Jakarta-Commons Database Connection Pool 要使用連接池需要如下的組件即jar文件

Jakarta-Commons DBCP 1.1 對應commons-dbcp-1.1.jar
Jakarta-Commons Collections 2.0 
對應commons-collections.jar
Jakarta-Commons Pool 1.1 
對應commons-pool-1.1.jar
這三個jar文件要與你的JDBC驅動程序一起放到【TOMCAT_HOME/common/lib目錄下以便讓tomcat和你的web應用都能夠找到。

7. Tomcat5.0下配置Hibernate3.0應用

7.1 Tomcat下建立數據庫連接池,如6中所示

7.2 Struts應用中添加Hibernate3.0支持

注意:hibernate.cfg.xml文件一定要存放到跟目錄下,默認的也就是/web應用/src,這個部署這個應用的時候hibernate.cfg.xml纔會出現在classes目錄下,也就是hibernate存放配置文件的默認錄入下.

由於我們採用Tomcat提供的數據庫連接池,所以這裏我們將是用自己創建的SessionFactory類。點擊完成MyEclipse會自動把Hibernate所需的的類庫加入到當前應用中。接下來就是配置Hibernate連接數據庫的所需的參數,以及性能參數(可選)。

既然我們選用應用服務器所提供的數據庫連接池,那麼在這裏我們只須要指定數據源的名字:java:comp/env/jdbc/TestDB,其中jdbc/TestDB就是我們在Tomcat中配置的數據源,也就是我們上面提到的jdbc/TestDB,資源名稱一定要匹配。其他的參數由於已經在Tomcat中配置過了,所以在這裏就不用配置了,Dialect一定要指定跟我們數據庫匹配的語言。既然我們選用應用服務器所提供的數據庫連接池,那麼在這裏我們只須要指定數據源的名字:java:comp/env/jdbc/TestDB,其中jdbc/TestDB就是我們在Tomcat中配置的數據源,也就是我們上面提到的jdbc/TestDB,資源名稱一定要匹配。其他的參數由於已經在Tomcat中配置過了,所以在這裏就不用配置了,Dialect一定要指定跟我們數據庫匹配的語言。

我們可以在這裏配置Hibernate一些調整性能的參數(針對不同的數據庫有些屬性可能無效)。

在這裏我們設置show_sqltrue,這樣在開發調試過程成控制檯可以打印真正在數據庫端執行的sql語句便於查找問題。其他一些屬性可以參閱http://www.hibernate.org/
到這裏Hibernate的配置已經基本完成,下面創建SessionFactory用來和數據庫進行交互(Hibernate官方文檔提供)。

package com.db;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class HibernateUtil {

 

    private static Log log =
LogFactory.getLog(HibernateUtil.class);

 

    private static final SessionFactory sessionFactory;

 

    static {

        try {

            sessionFactory = new Configuration().configure().
buildSessionFactory();

        } catch (Throwable ex) {

            log.error("Initial SessionFactory
creation failed.", ex);

            throw new ExceptionInInitializerError(ex);

        }

    }

 

    public static final ThreadLocal session = new ThreadLocal();

 

    public static Session currentSession()  {

        Session s = (Session) session.get();

        if (s == null) {

            s = sessionFactory.openSession();

            session.set(s);

        }

        return s;

    }

 

    public static void closeSession() {

        Session s = (Session) session.get();

        if (s != null)

            s.close();

        session.set(null);

    }

}

後面將會提到如何使用HibernateUtil,下面建立我們所需的數據庫
(略)我們可以使用208上的db_test_account這個數據庫中的表message來測試我們的Hibernate配置是否成功。數據庫樣例:

建表語句:

CREATE TABLE `message` (             

           `Id` varchar(50) NOT NULL default '0',  

           `text` varchar(50) default NULL,   

           `nextMessage` int(4) default NULL, 

           PRIMARY KEY  (`Id`)                

          ) TYPE=MyISAM

創建O/R Mapping:

點擊Edit

點擊New添加MySQL的驅動,保存

激活Database Explorer,保存。

選擇Database Explorer,創建數據庫鏈接:

點擊創建新的數據庫,添加所需必要的參數

保存,然後右鍵點擊該數據庫選擇open database,測試是否配置成功,如果不能連接查看該連接的配置參數。

點擊完成後MyEclipse會自動生成POJOMap文件,並更新Hibernate的配置文件(主要是加載Map文件)。ID Generator選項可以根據你的需要進行選擇,具體含義請參閱hibernate官方文檔。下面建立一個測試用的jsp頁面來看看Hibernate是否好用。
//MyJsp.jsp

<%@ page language="java" import="com.db.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+":
//"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">

   

    <title>My JSP 'MyJsp.jsp' starting page</title>

   

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

    <meta http-equiv="expires" content="0">

    <meta http-equiv="keywords" content="
keyword1,keyword2,keyword3">

    <meta http-equiv="description" content="This is my page">

   

    <!--

    <link rel="stylesheet" type="text/css" href="styles.css">

    -->

  </head>

 

  <body>

    <%   

               org.hibernate.Session s = HibernateUtil.currentSession();

               String hql = " from Message where text='b'";

               try {

                       org.hibernate.Query query = s.createQuery(hql);

                       java.util.List msgList = query.list();

                       hello.Message msg = (hello.Message) msgList.get(0);

                       out.println(msg.getId());

                       out.println(msg.getText());

                       out.println(msg.getNextmessage());                   

               } catch (org.hibernate.HibernateException e) {

                       e.printStackTrace();

               }             

               HibernateUtil.closeSession();        

    %>

  </body>

</html>

 

正常的結果如下:

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章