2009年3月20日
ant-1.63.jar http://ant.apache.org/ Ant 的核心包,在构建Hibernate 时会用到
antlr-2.7.5H3.jar http://www.antlr.org/ 语言转换工,Hibernate利用它实现 HQL 到 SQL的转换
asm.jar/asm-attrs.jar http://asm.objectweb.org/ ASM 字节转换库
c3p0-0.8.5.2.jar http://sourceforge.net/projects/c3p0 C3PO JDBC 连接池工具
cglib-2.1.jar http://cglib.sourceforge.net/ 高效的代码生成工具, Hibernate用它在运行时扩展 Java类和实现 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/ 用连接多个应用服务器的标准连接器
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/ 标准的 Java 权限和认证服务包
jaxen-1.1-beta-4.jar http:jaxen.org/ 通用的 XPath 处理引 擎
jboss-cache.jar http://www.jboss.com/products/jbosscache JBoss 的一种树状缓存实现工具
jboss-common.jar http://jboss.org/ Jboss 的基础包,在使用 JBoss 的树状缓存时必须有此包
jboss-jmx.jar http://jboss.org/ JBoss 的 JMX 实现包
jboss-system.jar http://jboss.org/ JBoss 的核心,包括服务器和部署引擎
jdbc2_0-stdext.jar http://java.sun.com/products/jdbc/download.html#spec 标准的 JDBC 2.0 扩展API
jgroups2.2.7.jar http://www.jgroups.org/ 网络通信工具包
jta.jar http://java.sun.com/products/jta 标准的 JAVA 事务处理接口
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 版本检查工具包,用于在构建 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语言中标准的XML 解析器
2009年3月11日
Action类的工作机制
所有的Action类是org.apache.struts.action.Action的子类。Action子类应该覆盖父类的execute方法。当ActionForm Bean被创建,并且表单验证顺利通过后,Struts框架就会调用Action类的execute()方法。execute()方法如下定义:
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)throws IOException,ServletException
execute()方法包含以下参数:
ActionMapping:包含了这个Action的配置信息,和struts-config.xml文件中的<action>元素对应。
ActionForm:包含了用户的表单数据,当Struts框架调用execute()方法时,ActionForm中的数据已经通过了表单验证。
HttpServletRequest:当前的HTTP请求对象。
HttpServletResponse:当前的HTTP响应对象。
访问封装在MessageResources中的本地化文本
Action类的execute()方法首先获得MessageResources对象:
MessageResources messages=getResources(request);
在Action类中定义了getResources(HttpServletRequest request)方法,该方法返回当前默认的MessageResources对象,它封装了Resource Bundle中的文本内容。接下来Action类就可以通过MessageResources对象来访问文本内容。例如,如果要读取消息KEY为“hello.jsp.title”对应的文本内容,可以调用MessageResources类的getMessage(String key)方法:
String title=messages.getMessage("hello.jsp.title");
业务逻辑验证
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”,将创建包含错误信息的ActionMessage对象,ActionMessage对象被保存岛ActionMessages对象中。接下来调用在Action基类中定义的saveErrors()方法,它负责把ActionMessages对象保存岛request范围内。最后返回ActionForward对象,Struts框架会根据ActionForward对象包含的转发信息把请求转发岛恰当的视图组件,视图组件通过<html:errors>标签把request范围内的ActionMessage对象中包含的错误消息显示出来,提示用户修改错误。
几乎所有和用户交互的应用都需要数据验证,而从头设计并开发完善的数据验证机制往往很费时。幸运的是,Struts框架提供了现成的、易于使用的数据验证功能。Struts框架的数据验证可分为两种类型:表单验证和业务逻辑验证,在本例中,它们分别运用于以下场合:
表单验证:如果用户没有在表单中输入姓名就提交表单,将生成表单验证错误。
业务逻辑验证:如果用户在表单中输入姓名为“Monster”,按照本应用的业务规则,则不允许向“Monster”打招呼,因此将生成业务逻辑错误。
第一种类型的验证,即表单验证由Action Bean来负责处理。
这个工作可以用以上的HelloForm.java的validate()方法负责完成这一任务:
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;
}
第二种类型的验证,即业务逻辑验证由Action来负责处理。
例:
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"));
}
}
创建ActionForm Bean
当用户提交HTML表单后,Struts框架将自动把表单数据组装到ActionForm Bean中。ActionForm Bean 中的属性和HTML表单中的字段一一对应。ActionForm Bean还提供数据验证方法,以及把属性重新设置为默认值的方法。Struts框架中定义的ActionFrom类是抽象的,必须在应用中创建它的子类,来存放具体的HTML表单数据。
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 实质上是一种JavaBean,不过它除了具有JavaBean的常规方法,还有两种特殊方法:
validate():用于表单验证。
reset:把属性重新设置为默认值。
hello.jsp使用<bean:message>标签来输出文本内容。这些文件来自于Resource Bundle,每个Resource Bundle 都对应一个或多个本地化的消息资源文件。资源文件为
application.properties:
#SDFSALKFJSLAKFLAK
//#为资源文件的注释
hello.jsp.title=Hello-A first Struts program
对于JSP代码:
<bean:message key="hello.jsp.title"/>
<bea:message>标签的key属性为“hello.jsp.title”,Resource Bundle中与匹配的内容为:
hello.jsp.title=Hello-A first Struts program
因此,以上<bean:message>标签将把“Hello-A first Struts program”输出岛网页上。
ActionServlet接收到一个客户请求时,将执行如下流程。
1、检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效的信息。
2、如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存岛ActionForm对象中。
3、根据配置信息决定是否需要表单验证,如果需要验证,就调用ActionForm的validate()方法。
4、如果AcctionForm的validate()方法返回null或返回一个不包含ActionMessage的ActionErrors对象,就表示表单验证成功。
5、ActionServlet 根据ActionMapping实例包含的映射信息决定将请求转发给哪个Action。如果相应的Action实例不存在,就先创建这个实例,然后用Action的execute()方法。
6、Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指向的JSP组件。
7、ActionForward对象指向的JSP组件生成动态网页,返回给客户。
对于以上流程的流程4,如果ActionForm的validate()方法返回一个包含一个或多个ActionMessage的ActionErrors对象,就表示表单失败,此时ActionServlet将直接把请求转发给包含用户提交表单的JSP组件。在这种情况下,不会再创建Action对象并调用Action的execute()方法。
HttpServletRequest:Servlet容器把HTTP请求信息保存在HttpServletRequest对象中,Servlet组件从request对象中读取用户的请求数据。此外,HttpServletRequest可以存放request范围内的共享数据。
HttpServletResponse:用于生成HTTP响应结果。
HttpSession:Servlet容器为每个WEB应用创建一个ServletContext实例,ServletContext可以存放application范围的共享数据。
HttpServletRequest、HttpSession、ServletContext分别提供在request、session、application范围内保存和读取共享数据的方法:
//save shared data
setAttribute(String key,Object value);
//get shared data
getAttribute(String key);
在保存共享数据时,应该指定属性KEY。在读取共享数据时,将根据这个属性KEY来检索共享数据。
例:
把ShoppingCart对象(购物车)存放在session范围内,存放时指定属性KEY卫“cart”,然后再通过这个属性KEY把ShoppingCart对象检索出来:
ShoppingCart shoppingCart=new ShoppingCart();
ShoopingCart myCart=null;
//sava cart
session.setAttribute("cart",shoppingCart);
//get cart
myCart=(ShoppingCart)session.getAttribute("cart");
请求转发:
Servlet的service()方法中执行以下代码:
RequestDispatcher rd=request.getRequestDispatcher("hello.jsp");
//Forward to requested URL
rd.forward(request,response);
在JSP页面中,可以使用<jsp:forward>标签来转发请求
例如:
<jsp:forward page="hello.jsp"/>
请求重定向:
WEB组件可以将请求重定向到任意URL,而不仅仅是同一应用中的URL。
重定向的源组件和目标组件之间不共用同一个HttpServletRequest对象,因此不能共享request范围内的共享数据。
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对象从内存中转移到文件系统或数据库中。
在访问HTTPSESSION信息时再把他们加载到内存中。
好处:
1、假如有一万个人同时在访问某个WEB应用,SERVLET容器中会生成一万个HTTPSESSION对象。如果吧这些对象都一直存放在内存中,将消耗大量的内存资源。显然不可取,因此可
以把处于不活动状态的HTTPSESSION对象转移到文件系统或数据库中,这样可以提高对内存。资源的利用率。
2、假定某个客户正在一个购物网站上购物,它将购买的物品先放在虚拟的购物车HTTPSESSION对象中。如果此时WEB服务器突然出现故障而终止,那么内存中的HTTPSESSION对象联
通客户的购物信息都会丢失。如果吧HTTPSESSION对象实现保存在文件系统或数据库中,当WEB服务器重启后,还可以从文件系统或数据库中恢复SESSION数据
比如:在网上书店应用中,从一个客户开始购物,到最后结账,整个过程是一个Session.
Servlet API中定义了javax.servlet.http.HttpSession接口,Servlet容器必须实现这一接口。当一个Session开始时,Servlet容器将创建一个HttpSession对象,在HttpSession对象中可以存放客户状态的信息。Servelt容器为HttpSession分配一个唯一标识符,称为Session ID.Servlet容器把Session ID作为Cookie保存在客户的浏览器中。每次客户发出HTTP请求时,Servlet容器可以从HttpRequest对象中读取Session ID,然后根据SessionID找到相应的HttpSession对象,从而获取客户的状态信息。
HttpSession接口中的方法:
getId():返回Session的ID;
invalidate():使当前的Session失效,Servlet容器会释放HttpSession对象占用的资源。
setAttribute(String name,Object value):将一对name/Value属性保存在HttpSession对象中
getAttribut(String name):根据name参数返回保存在HttpSession对象的属性值。
getAttributeNames():以数组的方式HttpSession对象中所有的属性名。
isNew():判断是否是新创建的Session,如果是新创建的Session,返回true,否则返回false
setMaxInactiveInterval():设定一个Session可以处于不活动状态的最大时间间隔,以秒为单位。如果超过这个时间。Session自动失效,如果设置为负数,表示不限制Session付出与不活动状态的时间。
getMaxInactiveInterval()读取当前Sessions可以处于不活动状态的最大时间间隔。
在Java Servlet API中提出了跟踪Session的另一种机制,如果客户浏览器不支持Cookie,Servlet容器可以重写客户请求的URL,吧Session ID添加到URL信息中。
HttpServletResponse接口提供了重写URL的方法:
public java.lang.String encodeURL(java.lang.String url)
该方法的实现机制为:
先判断当前的Web组件是否启用Session,如果没有启用Session,例如在JSP中声明
<%@ page session="false"%>或者已经执行了session.invalidate()方法,那么直接返回参数URL
再判断客户浏览器是否支持Cookie,如果支持Cookie,就直接返回参数URL;如果不支持,就在参数URL中加入Session ID信息,然后返回修改后的URL.
转发JSP请求
<jsp:forward>用于将客户请求重定向到其他的HTML文件、JSP文件或者Servlet文件。
<jsp:forward>语法:
<jsp:forward page="重定向的文件"/>
<jsp:forward>标签从一个JSP文件向另一个文件传递包含用户请求的request对象。
如果使用了这个标签,那么这个JSP文件中的所有输出数据都不会被发送到客户端,并且这个标签以下的代码不会被执行。