一、前言
二、相關概念與工具介紹
三、實例需求與總體設計
四、持久化層與業務層實踐(Hibernate實踐)
五、控制層與表示層實踐(Struts實踐)
六、發布與運行
七、寫在最后
一、前言
J2EE和.NET是目前企業級運用的兩大陣營,誰優誰劣各有說法。筆者是做J2EE方向的,覺得J2EE比起.NET最大的優勢就是其經過長實踐發展總結出來的大量模式和大量先進的框架。這些框架許多都是開源的——開源也是J2EE陣營的另一優勢。本篇文章的主角就是目前J2EE web應用中最流行的兩大開源框架——Hibernate和Struts。
二、相關概念與工具介紹
下面我將分別對本文“三大主角”所涉及到相關概念進行說明。
Hibernate及相關知識介紹
Hibernate:
中文意思是"冬眠“,呵呵,不知道設計者為何用這個名字。它是一個開源的ORM框架(關于ORM下文還會講解),它是通過對JDBC API進行封裝從而實現對java對象持久化的。有人可能要問:JDBC其實不難操作,為什么還要封裝它哪?其實答案很簡單,因為現在通用的數據庫都是關系數據庫,我們通過JDBC操作無法做到OOP,所以Hibernate將JDBC封裝起來,并且提供了一套OO化的Hibernate API供頂層操作。Hibernate現在幾乎已經成為ORM的公認標準了(剛推出的EJB 3.0標準中使用的ORM事實上就是Hibernate)
ORM:
這里解釋下ORM。ORM是一種模式(關于模式,筆者之前在這里發表過一篇介紹工廠模式的文章,讀者可以看看),它的英文是Object-Relation Mapping,中譯為對象-關系映射,它指的是“在單個組建中負責所有實體域對象的持久化,封裝數據訪問細節”(注:此定義來自《精通Hibernate:java對象持久化技術詳解》,孫衛琴,電子工業出版社)。筆者的覺得很容易理解:把關系數據庫對象化。
Struts及相關知識介紹
Struts:
Struts是由著名的Apache基金會開發的開源項目。中譯為“框架”,顧名思義,它就是一種MVC框架。眾所周知,MVC是一種業務邏輯與表示分離的模式,在java web上的應用十分廣泛。以前MVC的主要表現形式是JSP Model2,也就是JSP+Servlet+Javabean的應用,而近年來Struts的應用越來越廣泛,目前已經是最流行的MVC框架了。
MVC:
Model-View-Controller,中譯為模型-視圖-控制器。MVC不是真正意義上的軟件設計模式,而更是一種解決方案,它把軟件系統的所有業務邏輯方面的編程交給了Model,把所有UI視圖的設計和編程交給了View,再用Controller控制器控制Model并生成相應的View,從而真正實現了業務邏輯與用戶界面的分離。
Eclipse介紹
Eclipse是由IBM公司開發出來,后來又免費捐獻出來的開源工具,是一套主要用于Java開發的IDE(Eclipse通過添加某些插件可以實現對UML、C++等的開發)。Eclipse具有強大的擴展功能,加上其開源的特性,導致許多愛好者和公司為其開發了非常優秀的插件,Myeclipse就是其中之一。Myeclipse是面向J2EE開發者的Eclipse插件,功能強大,好用。本文的實例就是基于Eclipse+Myeclipse環境下開發出來的。
創建/運行本文實例除了安裝以上工具和插件外還需要安裝一個Web容器,本文使用的是Jboss,筆者可以自行選擇使用Tomcat或Weblogic等,這些對運行本文實例影響不大。
本文選擇的數據庫是SQLServer2000,關于Mysql、Oracle等其他數據庫的操作方法類似。
關于Eclipse下載和安裝方法本文不做介紹,請讀者自行在網上查找相關方法。
三、實例需求與總體設計
1、需求定義
由于本文的目的是介紹在Eclipse IDE下開發Struts+Hibernate的具體方法,而不是介紹項目開發/軟件設計的技巧,所以本文實例需求非常簡單。
本文實例是一個web留言簿,可以讓匿名用戶發表一些留言信息,并保存至數據庫。做過web開發的朋友肯定做過這類實例,非常經典。由于實例簡單并且容易理解,所以筆者也省去畫用例圖說明的步驟。
2、總體設計
本實例按傳統J2EE web項目的設計方法,分為5層架構,自底向上分別是:數據庫層 -> ORM層(Hibernate層) -> 業務邏輯層 -> 控制層(Struts Action) -> 視圖表示層。
數據庫的DDL語句如下:
四、持久化層與業務層實踐(Hibernate實踐)
好,戲肉開始。
1、先打開Eclipse。點擊“新建項目”->“Web Project”,出現如下窗口,在窗口中Project Name填入“Memo”作為項目名:
create database memotest
create table Memo
(
ID int not null identity(1,1),
topic varchar(255),
content text,
guest varchar(50),
primary key(ID)
)
?
2、點擊“窗口”->“打開透視圖”->“其他”,出現如下窗口,雙擊“Myeclipse Database Explorer”,切換到如下視圖:
3、在“DB Browser”控制面板點擊“new”,新建一個數據庫連接。在彈出的窗口中點擊“new driver”新建一個數據庫連接驅動。如下圖:
4、上一步后回到以下視圖,在列表中選擇上一步創建的驅動,填入相關數據庫資料,點擊確定即可。(此步驟前必須已經打開數據庫,最后已經按照本實例的DDL創建了庫和表)
5、完成上一步后出現以下視圖。點擊“memo”的右鍵,點擊“open connetion”->“確定”。如果上述步驟成功的話這里會連接到數據庫,并顯示相關的數據庫結構。
成功后如下圖:
6、點擊“窗口”->“打開透視圖”->“其他”->“Myeclipse”切換到項目控制視圖。在項目名上點擊右鍵->“myeclipse”->“Add Hibernate capabilites”,出現以下視圖,并按下圖填入相關信息:
點下一步后出現如下框圖,按圖片上內容填寫:
提交后出現以下視圖,按圖片內容填寫:
7、在項目名上點擊右鍵->“myeclipse”->“Add Struts capabilites”,出現下面視圖,按圖中內容天下:
8、點擊“窗口”->“打開透視圖”->“其他”,出現如下窗口,雙擊“Myeclipse Database Explorer”,切換到數據庫管理視圖,找到我們為本次實例創建的表格,點右鍵->“create hibernate mapping”后出現下圖,按圖上內容填寫:
9、至此Hibernate的創建工作已經完成,如下圖,接下來我們寫個DAO工廠類來操作Hibernate API。
點擊com.woden包,新建個類,如下圖:
輸入以下代碼:
package com.woden;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
public class MemoDAOFactory {
? ? ? ? Session session;
? ? Transaction tx;
? ?
? ? public void add(Memo memo) throws HibernateException{
? ?? ?? ?? ?try{
? ?? ?? ?? ?? ?? ???session = SessionFactory.currentSession();
? ?? ?? ?? ?? ?? ???tx = session.beginTransaction();
? ?? ?? ?? ?? ?? ???session.save(memo);
? ?? ?? ?? ?? ?? ???tx.commit();
? ?? ?? ?? ?}catch(HibernateException e){
? ?? ?? ?? ?? ?? ???System.out.println(e.toString());
? ?? ?? ?? ?}finally{
? ?? ?? ?? ?? ?? ???if(tx!=null){
? ?? ?? ?? ?? ?? ?? ?? ?? ? tx.rollback();
? ?? ?? ?? ?? ?? ???}
? ?? ?? ?? ?? ?? ???SessionFactory.closeSession();
? ?? ?? ?? ?}
? ? }
}
以上只有一個插入方法,如果讀者需要更多方法可以在DAO中自行添加。
至此,數據庫層、ORM層和業務層的代碼已經完成。
五、控制層與表示層實踐(Struts實踐)
1、新建一個welcome.jsp文件,作為實例的首頁。具體方法是在“webroot”文件夾圖標點右鍵->new->“jsp”,接下來填寫的東西很簡單就不用介紹了吧。
2、在上一步驟的第7步中已經在myeclipse中導入了struts,我們下面就可以開始編輯設置我們的struts實例。打開webboot目錄下WEB-INF中的struts配置文件“struts-config.xml”,如下圖:
3、在屏幕空白處點右鍵->“new”->“new form,action and jsp”,會出現如下視圖,按下圖提示填寫內容:
這里記得點擊“jsp”標簽條,出現以下界面,按下圖設置:
4、上一步驟設置了form,點擊下一步看到如下視圖,按下圖設置,具體步驟是:點擊“foward”標簽->“add”->name填“success”,path選擇“welcome.jsp”,其他不用填->確定。
5、上一步驟點擊了“完成”后出現下圖:
6、這一步驟是設置資源文件,為了struts的國際化和錯誤提示做準備。找到項目文件夾中src(源文件夾),找到ApplicationResourse.properties,雙擊打開,如下圖所示配置:(注:這里筆者安裝了一個免費的ascii轉unicode的插件)
如果讀者沒有安裝ascii自動轉unicode組建,可以直接copy我轉換后的資源文件內容:
form.addmemo.err.content=\u7559\u8a00\u5185\u5bb9\u4e0d\u80fd\u4e3a\u7a7a\u3002
form.addmemo.err.guest=\u7559\u8a00\u8005\u59d3\u540d\u4e0d\u80fd\u4e3a\u7a7a\u3002
form.addmemo.err.topic=\u7559\u8a00\u6807\u9898\u4e0d\u80fd\u4e3a\u7a7a\u3002
jsp.addmemo.content=\u8bf7\u8f93\u5165\u5185\u5bb9\uff1a
jsp.addmemo.guest=\u60a8\u7684\u59d3\u540d\uff1a
jsp.addmemo.pagetitle=\u7559\u8a00\u6dfb\u52a0
jsp.addmemo.reset=\u91cd\u8bbe
jsp.addmemo.submit=\u63d0\u4ea4
jsp.addmemo.topic=\u6807\u9898\uff1a
jsp.welcome.content=\u6b22\u8fce\u4f7f\u7528Hibernate+Struts\u5b9e\u4f8b\u3002
jsp.welcome.title=\u4f60\u597d\u3002\u3002\u3002
7、下面打開com.woden.form.MemoForm.java文件,輸入以下代碼:
package com.woden.form;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
public class MemoForm extends ActionForm {
? ? ? ? private String topic;
? ? ? ? private String content;
? ? ? ? private String guest;
? ? ? ? public ActionErrors validate(
? ? ? ? ? ? ? ? ActionMapping mapping,
? ? ? ? ? ? ? ? HttpServletRequest request) {
? ? ? ? ? ? ? ? ActionErrors errors = new ActionErrors();
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(getGuest()==null||"".equals(getGuest()))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? errors.add("memoform.err.guest",new ActionMessage("form.addmemo.err.guest"));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(getTopic()==null||"".equals(getTopic()))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? errors.add("memoform.err.topic",new ActionMessage("form.addmemo.err.topic"));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(getContent()==null||"".equals(getContent()))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? errors.add("memoform.err.content",new ActionMessage("form.addmemo.err.content"));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? return errors;
? ? ? ? }
? ? ? ? public void reset(ActionMapping mapping, HttpServletRequest request) {
? ? ? ? ? ? ? ? this.topic=null;
? ? ? ? ? ? ? ? this.content=null;
? ? ? ? ? ? ? ? this.guest=null;
? ? ? ? }
? ? ? ? public String getTopic() {
? ? ? ? ? ? ? ? return topic;
? ? ? ? }
? ? ? ? public void setTopic(String topic) {
? ? ? ? ? ? ? ? this.topic = topic;
? ? ? ? }
? ? ? ? public String getContent() {
? ? ? ? ? ? ? ? return content;
? ? ? ? }
? ? ? ? public void setContent(String content) {
? ? ? ? ? ? ? ? this.content = content;
? ? ? ? }
? ? ? ? public String getGuest() {
? ? ? ? ? ? ? ? return guest;
? ? ? ? }
? ? ? ? public void setGuest(String guest) {
? ? ? ? ? ? ? ? this.guest = guest;
? ? ? ? }
}
8、上面已經寫出了ActionForm的代碼,具體代碼筆者在這里不解釋,我想看過struts基礎的朋友都應該很清楚了,下面貼處Action的代碼:
package com.woden.action;
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.woden.Memo;
import com.woden.MemoDAOFactory;
import com.woden.form.MemoForm;
public class MemoAction extends Action {
? ? ? ? public ActionForward execute(
? ? ? ? ? ? ? ? ActionMapping mapping,
? ? ? ? ? ? ? ? ActionForm form,
? ? ? ? ? ? ? ? HttpServletRequest request,
? ? ? ? ? ? ? ? HttpServletResponse response) {
? ? ? ? ? ? ? ? MemoForm memoForm = (MemoForm) form;
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? MemoDAOFactory memoDAO = new MemoDAOFactory();
? ? ? ? ? ? ? ? Memo memo = new Memo();
? ? ? ? ? ? ? ? memo.setTopic(memoForm.getTopic());
? ? ? ? ? ? ? ? memo.setContent(memoForm.getContent());
? ? ? ? ? ? ? ? memo.setGuest(memoForm.getGuest());
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? try{
? ? ? ? ? ? ? ? ? ? ? ? memoDAO.add(memo);? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }catch(Exception e)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? System.out.print(e.toString());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? return mapping.findForward("success");
? ? ? ? }
}
9、最后編輯下幾個相關jsp文件的內容,分別如下:
welcome.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html>
??<head>
? ? <html:base />
? ? <title><bean:message key="jsp.welcome.title"/></title>
??</head>
??
??<body>
? ? <bean:message key="jsp.welcome.content"/>
??</body>
</html:html>
addmemo.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<html>
? ? ? ? <head>
? ? ? ? ? ? ? ? <title><bean:message key="jsp.addmemo.pagetitle"/></title>
? ? ? ? </head>
? ? ? ? <body>
? ? ? ? ? ? ? ? <html:form action="/memo">
? ? ? ? ? ? ? ? ? ? ? ? <bean:message key="jsp.addmemo.guest"/><html:text property="guest"/><html:errors property="memoform.err.guest"/><br/>
? ? ? ? ? ? ? ? ? ? ? ? <bean:message key="jsp.addmemo.topic"/><html:text property="topic"/><html:errors property="memoform.err.topic"/><br/>
? ? ? ? ? ? ? ? ? ? ? ? <bean:message key="jsp.addmemo.content"/><html:textarea property="content"/><html:errors property="memoform.err.content"/><br/>
? ? ? ? ? ? ? ? ? ? ? ? <html:submit><bean:message key="jsp.addmemo.submit"/></html:submit>
? ? ? ? ? ? ? ? ? ? ? ? <html:reset><bean:message key="jsp.addmemo.reset"/></html:reset>
? ? ? ? ? ? ? ? </html:form>
? ? ? ? </body>
</html>
至此,本實例完成。
六、發布與運行
1、在項目文件點右鍵->“myeclipse”->“Add and remove project deployment”,如下圖:
2、點擊
圖標,選擇“Jboss”->“start”(注:這里如果用的是tomcat也類似操作,關于服務器配置的方法這里不祥談,請讀者自行在網上查找相關資料),會發現控制臺會輸出類似如下信息:
打開瀏覽器,輸入:http://localhost:8080/ 后如果出現下圖證明啟動成功:
3、輸入網址:http://localhost:8080/Memo/addmemo.jsp ,會看到效果圖如下圖:
4、按照正常流程和非正常流程分別留言一次,呵呵,效果出來沒有?如果沒有出現預期效果請檢查前面步驟。
七、寫在最后
在本文最后,筆者再次強調,本文的目的是介紹Eclipse IDE關于創建Struts+Hibernate應用的方法,而不是介紹j2ee框架的概念和運用,更不是介紹java設計與模式。本文對IDE的配置、服務器配置的方法也沒做詳細介紹,因為這都不是本文重點。對以上知識想了解多點的讀者可以google一下。
本文的實例只是一個入門,強調的是一種方法,而不是強調功能,所以本文的實例只有一個簡單的錄入功能。在看完本文后讀者可以添加更多的功能(我想,當這一架構搭建起來后,添加功能已經是相當容易的事情了)。