2009年3月20日
ant-1.63.jar http://ant.apache.org/ Ant 的核心包,在構(gòu)建Hibernate 時會用到
antlr-2.7.5H3.jar http://www.antlr.org/ 語言轉(zhuǎn)換工,Hibernate利用它實現(xiàn) HQL 到 SQL的轉(zhuǎn)換
asm.jar/asm-attrs.jar http://asm.objectweb.org/ ASM 字節(jié)轉(zhuǎn)換庫
c3p0-0.8.5.2.jar http://sourceforge.net/projects/c3p0 C3PO JDBC 連接池工具
cglib-2.1.jar http://cglib.sourceforge.net/ 高效的代碼生成工具, Hibernate用它在運行時擴展 Java類和實現(xiàn) Java 接口
commons-collections-2.1.1.jar http://jakarta.apache.org/commons/collections Apache 的工具集,用來增強Java對集合的處理能力
commons-logging-1.0.4.jar http://jakarta.apache.org/commons/logging/ Apache 軟件基我組所提供的日志工具
concurrent-1.3.2.jar http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html 線程同步工具,在使用JBoss 的樹狀緩存時需要用到
connector.jar http://java.sun.com/j2ee/connector/ 用連接多個應(yīng)用服務(wù)器的標(biāo)準(zhǔn)連接器
dom4j-1.6.jar http://dom4.j.org/ dom4j XML 解析器
ehcache-1.1.jar http://sourceforge.net/projects/echache 緩存工具.在沒有提供其他緩存工具時,這個緩存工具是必不可少的
jaas.jar http://java.sun.com/products/jass/ 標(biāo)準(zhǔn)的 Java 權(quán)限和認證服務(wù)包
jaxen-1.1-beta-4.jar http:jaxen.org/ 通用的 XPath 處理引 擎
jboss-cache.jar http://www.jboss.com/products/jbosscache JBoss 的一種樹狀緩存實現(xiàn)工具
jboss-common.jar http://jboss.org/ Jboss 的基礎(chǔ)包,在使用 JBoss 的樹狀緩存時必須有此包
jboss-jmx.jar http://jboss.org/ JBoss 的 JMX 實現(xiàn)包
jboss-system.jar http://jboss.org/ JBoss 的核心,包括服務(wù)器和部署引擎
jdbc2_0-stdext.jar http://java.sun.com/products/jdbc/download.html#spec 標(biāo)準(zhǔn)的 JDBC 2.0 擴展API
jgroups2.2.7.jar http://www.jgroups.org/ 網(wǎng)絡(luò)通信工具包
jta.jar http://java.sun.com/products/jta 標(biāo)準(zhǔn)的 JAVA 事務(wù)處理接口
junit-3.8.1.jar http://www.junit.org/ JUnit 測試框架
log4.j-1.2.9.jar http://logging.apache.org/log4j/ log4j 庫,Apache 的日志工具
oscache-2.1.jar http://www.opensymphony.com/oscache/ Java 對象的緩存工具
proxool-0.8.3.jar http://proxool.sourceforge.net/ Proxool JDBC 連接池 工具
swarmcache-1.0rc2.jar http://swarmcache.sourceforge.net/ Hibernate 可以使用的一種緩存工具
versioncheck.jar 版本檢查工具包,用于在構(gòu)建 Hibernate 的時候檢查輔助 jar 包文件的版本
xerces-2.6.2.jar http://xml.apache.org/xerces2-j/ SAX XML 解析器
xml-apis.jar http://xml.apache.org/xerces2-j/ Java語言中標(biāo)準(zhǔn)的XML 解析器
2009年3月11日
Action類的工作機制
所有的Action類是org.apache.struts.action.Action的子類。Action子類應(yīng)該覆蓋父類的execute方法。當(dāng)ActionForm Bean被創(chuàng)建,并且表單驗證順利通過后,Struts框架就會調(diào)用Action類的execute()方法。execute()方法如下定義:
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)throws IOException,ServletException
execute()方法包含以下參數(shù):
ActionMapping:包含了這個Action的配置信息,和struts-config.xml文件中的<action>元素對應(yīng)。
ActionForm:包含了用戶的表單數(shù)據(jù),當(dāng)Struts框架調(diào)用execute()方法時,ActionForm中的數(shù)據(jù)已經(jīng)通過了表單驗證。
HttpServletRequest:當(dāng)前的HTTP請求對象。
HttpServletResponse:當(dāng)前的HTTP響應(yīng)對象。
訪問封裝在MessageResources中的本地化文本
Action類的execute()方法首先獲得MessageResources對象:
MessageResources messages=getResources(request);
在Action類中定義了getResources(HttpServletRequest request)方法,該方法返回當(dāng)前默認的MessageResources對象,它封裝了Resource Bundle中的文本內(nèi)容。接下來Action類就可以通過MessageResources對象來訪問文本內(nèi)容。例如,如果要讀取消息KEY為“hello.jsp.title”對應(yīng)的文本內(nèi)容,可以調(diào)用MessageResources類的getMessage(String key)方法:
String title=messages.getMessage("hello.jsp.title");
業(yè)務(wù)邏輯驗證
ActionMessages errors=new ActionMessages();
String userName=(String)((HelloForm)form).getUserName();
String badUserName="Monster";
if(userName.equalsIgnoreCase(badUserName))
{
errors.add("username",new ActionMessage("hello.dont.talk.to.monster",badUserName));
saveErrors(request,errors);
return(new ActionForward(mapping.getInput()));
}
如果用戶輸入的姓名“Monster”,將創(chuàng)建包含錯誤信息的ActionMessage對象,ActionMessage對象被保存島ActionMessages對象中。接下來調(diào)用在Action基類中定義的saveErrors()方法,它負責(zé)把ActionMessages對象保存島request范圍內(nèi)。最后返回ActionForward對象,Struts框架會根據(jù)ActionForward對象包含的轉(zhuǎn)發(fā)信息把請求轉(zhuǎn)發(fā)島恰當(dāng)?shù)囊晥D組件,視圖組件通過<html:errors>標(biāo)簽把request范圍內(nèi)的ActionMessage對象中包含的錯誤消息顯示出來,提示用戶修改錯誤。
幾乎所有和用戶交互的應(yīng)用都需要數(shù)據(jù)驗證,而從頭設(shè)計并開發(fā)完善的數(shù)據(jù)驗證機制往往很費時。幸運的是,Struts框架提供了現(xiàn)成的、易于使用的數(shù)據(jù)驗證功能。Struts框架的數(shù)據(jù)驗證可分為兩種類型:表單驗證和業(yè)務(wù)邏輯驗證,在本例中,它們分別運用于以下場合:
表單驗證:如果用戶沒有在表單中輸入姓名就提交表單,將生成表單驗證錯誤。
業(yè)務(wù)邏輯驗證:如果用戶在表單中輸入姓名為“Monster”,按照本應(yīng)用的業(yè)務(wù)規(guī)則,則不允許向“Monster”打招呼,因此將生成業(yè)務(wù)邏輯錯誤。
第一種類型的驗證,即表單驗證由Action Bean來負責(zé)處理。
這個工作可以用以上的HelloForm.java的validate()方法負責(zé)完成這一任務(wù):
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
{
ActionErrors errors=new ActionErrors();
if((userName==null)||(userName.length())<1)
error.add("username",new ActionMessage("hello.no.username.error"));
return errors;
}
第二種類型的驗證,即業(yè)務(wù)邏輯驗證由Action來負責(zé)處理。
例:
package hello;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet.ServeltException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResource;
public final class HelloAction extends Action
{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)throws Exception
{
MessageResources message=getResources(request);
Action Messages errors=new ActionMessages();
String userName=(String)((HelloForm)form).getUserName();
//ActionMessages errors=new ActionMessage();
//String userName=(String)((HelloForm)form).getUserName();
String badUserName="Monster";
if(userName.equalslgnoreCase(badUserName))
{
errors.add("username",new ActionMessage("hello.dont.talk.to.monster",badUserName));
saveErrors(request,errors);
}
return (new ActionForward(mapping.getInput()));
}
PersonBean pd=new PersonBean();
pd.setUserName(userName);
pd.saveToPersistentStore();
request.setAttribute(Constants.PERSON_KEY,pd);
request.removeAttribute(mapping.getAttribute());
return(mapping.findForward("SayHello"));
}
}
創(chuàng)建ActionForm Bean
當(dāng)用戶提交HTML表單后,Struts框架將自動把表單數(shù)據(jù)組裝到ActionForm Bean中。ActionForm Bean 中的屬性和HTML表單中的字段一一對應(yīng)。ActionForm Bean還提供數(shù)據(jù)驗證方法,以及把屬性重新設(shè)置為默認值的方法。Struts框架中定義的ActionFrom類是抽象的,必須在應(yīng)用中創(chuàng)建它的子類,來存放具體的HTML表單數(shù)據(jù)。
package hello;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public final class HelloForm extends ActionForm
{
private String userName=null;
public String getUserName(){
return(this.userName);
}
public void setUserName(String userName)
{
this.userName=userName;
}
public void reset(ActionMapping mapping,HttpServletRequest request)
{
this.userName=null;
}
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request)
{
ActionErrors errors=new ActionErrors();
if((userName==null)||(userName.length()<1))
errors.add("username",new ActionMessage("hello.no.username.error"));
return errors;
}
}
ActionForm Bean 實質(zhì)上是一種JavaBean,不過它除了具有JavaBean的常規(guī)方法,還有兩種特殊方法:
validate():用于表單驗證。
reset:把屬性重新設(shè)置為默認值。
hello.jsp使用<bean:message>標(biāo)簽來輸出文本內(nèi)容。這些文件來自于Resource Bundle,每個Resource Bundle 都對應(yīng)一個或多個本地化的消息資源文件。資源文件為
application.properties:
#SDFSALKFJSLAKFLAK
//#為資源文件的注釋
hello.jsp.title=Hello-A first Struts program
對于JSP代碼:
<bean:message key="hello.jsp.title"/>
<bea:message>標(biāo)簽的key屬性為“hello.jsp.title”,Resource Bundle中與匹配的內(nèi)容為:
hello.jsp.title=Hello-A first Struts program
因此,以上<bean:message>標(biāo)簽將把“Hello-A first Struts program”輸出島網(wǎng)頁上。
ActionServlet接收到一個客戶請求時,將執(zhí)行如下流程。
1、檢索和用戶請求匹配的ActionMapping實例,如果不存在,就返回用戶請求路徑無效的信息。
2、如果ActionForm實例不存在,就創(chuàng)建一個ActionForm對象,把客戶提交的表單數(shù)據(jù)保存島ActionForm對象中。
3、根據(jù)配置信息決定是否需要表單驗證,如果需要驗證,就調(diào)用ActionForm的validate()方法。
4、如果AcctionForm的validate()方法返回null或返回一個不包含ActionMessage的ActionErrors對象,就表示表單驗證成功。
5、ActionServlet 根據(jù)ActionMapping實例包含的映射信息決定將請求轉(zhuǎn)發(fā)給哪個Action。如果相應(yīng)的Action實例不存在,就先創(chuàng)建這個實例,然后用Action的execute()方法。
6、Action的execute()方法返回一個ActionForward對象,ActionServlet再把客戶請求轉(zhuǎn)發(fā)給ActionForward對象指向的JSP組件。
7、ActionForward對象指向的JSP組件生成動態(tài)網(wǎng)頁,返回給客戶。
對于以上流程的流程4,如果ActionForm的validate()方法返回一個包含一個或多個ActionMessage的ActionErrors對象,就表示表單失敗,此時ActionServlet將直接把請求轉(zhuǎn)發(fā)給包含用戶提交表單的JSP組件。在這種情況下,不會再創(chuàng)建Action對象并調(diào)用Action的execute()方法。
HttpServletRequest:Servlet容器把HTTP請求信息保存在HttpServletRequest對象中,Servlet組件從request對象中讀取用戶的請求數(shù)據(jù)。此外,HttpServletRequest可以存放request范圍內(nèi)的共享數(shù)據(jù)。
HttpServletResponse:用于生成HTTP響應(yīng)結(jié)果。
HttpSession:Servlet容器為每個WEB應(yīng)用創(chuàng)建一個ServletContext實例,ServletContext可以存放application范圍的共享數(shù)據(jù)。
HttpServletRequest、HttpSession、ServletContext分別提供在request、session、application范圍內(nèi)保存和讀取共享數(shù)據(jù)的方法:
//save shared data
setAttribute(String key,Object value);
//get shared data
getAttribute(String key);
在保存共享數(shù)據(jù)時,應(yīng)該指定屬性KEY。在讀取共享數(shù)據(jù)時,將根據(jù)這個屬性KEY來檢索共享數(shù)據(jù)。
例:
把ShoppingCart對象(購物車)存放在session范圍內(nèi),存放時指定屬性KEY衛(wèi)“cart”,然后再通過這個屬性KEY把ShoppingCart對象檢索出來:
ShoppingCart shoppingCart=new ShoppingCart();
ShoopingCart myCart=null;
//sava cart
session.setAttribute("cart",shoppingCart);
//get cart
myCart=(ShoppingCart)session.getAttribute("cart");
請求轉(zhuǎn)發(fā):
Servlet的service()方法中執(zhí)行以下代碼:
RequestDispatcher rd=request.getRequestDispatcher("hello.jsp");
//Forward to requested URL
rd.forward(request,response);
在JSP頁面中,可以使用<jsp:forward>標(biāo)簽來轉(zhuǎn)發(fā)請求
例如:
<jsp:forward page="hello.jsp"/>
請求重定向:
WEB組件可以將請求重定向到任意URL,而不僅僅是同一應(yīng)用中的URL。
重定向的源組件和目標(biāo)組件之間不共用同一個HttpServletRequest對象,因此不能共享request范圍內(nèi)的共享數(shù)據(jù)。
response.sendRedirect("http://jakarta.apache.org/struts/");
包含:
Servlet類使用javax.servlet.RequestDispatcher.include()
RequsetDispatcher rd;
rd=req.getRequestDispatcher("/header.jsp");
在JSP文件中,可以通過<include>指令來包含其他的WEB資源,
<%@ include file="header.jsp"%>
Servlet持久化
Servlet容器在某些情況下把這些HttpSession對象從內(nèi)存中轉(zhuǎn)移到文件系統(tǒng)或數(shù)據(jù)庫中。
在訪問HTTPSESSION信息時再把他們加載到內(nèi)存中。
好處:
1、假如有一萬個人同時在訪問某個WEB應(yīng)用,SERVLET容器中會生成一萬個HTTPSESSION對象。如果吧這些對象都一直存放在內(nèi)存中,將消耗大量的內(nèi)存資源。顯然不可取,因此可
以把處于不活動狀態(tài)的HTTPSESSION對象轉(zhuǎn)移到文件系統(tǒng)或數(shù)據(jù)庫中,這樣可以提高對內(nèi)存。資源的利用率。
2、假定某個客戶正在一個購物網(wǎng)站上購物,它將購買的物品先放在虛擬的購物車HTTPSESSION對象中。如果此時WEB服務(wù)器突然出現(xiàn)故障而終止,那么內(nèi)存中的HTTPSESSION對象聯(lián)
通客戶的購物信息都會丟失。如果吧HTTPSESSION對象實現(xiàn)保存在文件系統(tǒng)或數(shù)據(jù)庫中,當(dāng)WEB服務(wù)器重啟后,還可以從文件系統(tǒng)或數(shù)據(jù)庫中恢復(fù)SESSION數(shù)據(jù)
比如:在網(wǎng)上書店應(yīng)用中,從一個客戶開始購物,到最后結(jié)賬,整個過程是一個Session.
Servlet API中定義了javax.servlet.http.HttpSession接口,Servlet容器必須實現(xiàn)這一接口。當(dāng)一個Session開始時,Servlet容器將創(chuàng)建一個HttpSession對象,在HttpSession對象中可以存放客戶狀態(tài)的信息。Servelt容器為HttpSession分配一個唯一標(biāo)識符,稱為Session ID.Servlet容器把Session ID作為Cookie保存在客戶的瀏覽器中。每次客戶發(fā)出HTTP請求時,Servlet容器可以從HttpRequest對象中讀取Session ID,然后根據(jù)SessionID找到相應(yīng)的HttpSession對象,從而獲取客戶的狀態(tài)信息。
HttpSession接口中的方法:
getId():返回Session的ID;
invalidate():使當(dāng)前的Session失效,Servlet容器會釋放HttpSession對象占用的資源。
setAttribute(String name,Object value):將一對name/Value屬性保存在HttpSession對象中
getAttribut(String name):根據(jù)name參數(shù)返回保存在HttpSession對象的屬性值。
getAttributeNames():以數(shù)組的方式HttpSession對象中所有的屬性名。
isNew():判斷是否是新創(chuàng)建的Session,如果是新創(chuàng)建的Session,返回true,否則返回false
setMaxInactiveInterval():設(shè)定一個Session可以處于不活動狀態(tài)的最大時間間隔,以秒為單位。如果超過這個時間。Session自動失效,如果設(shè)置為負數(shù),表示不限制Session付出與不活動狀態(tài)的時間。
getMaxInactiveInterval()讀取當(dāng)前Sessions可以處于不活動狀態(tài)的最大時間間隔。
在Java Servlet API中提出了跟蹤Session的另一種機制,如果客戶瀏覽器不支持Cookie,Servlet容器可以重寫客戶請求的URL,吧Session ID添加到URL信息中。
HttpServletResponse接口提供了重寫URL的方法:
public java.lang.String encodeURL(java.lang.String url)
該方法的實現(xiàn)機制為:
先判斷當(dāng)前的Web組件是否啟用Session,如果沒有啟用Session,例如在JSP中聲明
<%@ page session="false"%>或者已經(jīng)執(zhí)行了session.invalidate()方法,那么直接返回參數(shù)URL
再判斷客戶瀏覽器是否支持Cookie,如果支持Cookie,就直接返回參數(shù)URL;如果不支持,就在參數(shù)URL中加入Session ID信息,然后返回修改后的URL.
轉(zhuǎn)發(fā)JSP請求
<jsp:forward>用于將客戶請求重定向到其他的HTML文件、JSP文件或者Servlet文件。
<jsp:forward>語法:
<jsp:forward page="重定向的文件"/>
<jsp:forward>標(biāo)簽從一個JSP文件向另一個文件傳遞包含用戶請求的request對象。
如果使用了這個標(biāo)簽,那么這個JSP文件中的所有輸出數(shù)據(jù)都不會被發(fā)送到客戶端,并且這個標(biāo)簽以下的代碼不會被執(zhí)行。