摘 要
今天,越来越多的开发者想要编写企业级分布式的事务处理应用程序,而这些应用程序必须可以提供高性能、安全性和服务器端的可靠性。在这个高速发展、要求苛刻的电子商务和信息技术的世界中,企业级的应用程序必须具有以下特点:花费更少的金钱、具有更快的速度、占用更少的资源。
本文所研究的StrutsEJB是一个开放源码的类库,它使用Struts、EJB和JSTL能够快速地创建基于J2EE的web应用。
StrutsEJB框架与MVC(Model/View/Controller)模式的对应关系是:EJBCommand就是Model,Struts是Controller,JSP页面是View。它有如下特点:第一,只需要把业务逻辑添加到一个EJBCommand类中,而无需新创建一个会话bean。第二,基于镜像的DTO和反映射的ActionForm,无需不断的访问存取器。第三,StrutsEJB的DTOFactory类能够自动的监测到各个域,并且在ActionForm、DTO和实体Bean之间进行值的拷贝。第四,定位服务和业务代理能够减少在web层上的依赖于EJB的代码量。第五,数据库的访问十分简单,并且表的内容可以使用JSTL标签显示出来。第六,在安全方面,它具有基于角色的用户管理和个性化的工具。产品级的QA组织已经对StrutsEJB进行了无数次的精炼,现在已经应用到了商业项目中。它为J2EE应用提供了坚固而稳定的基础。
本论文将对StrutsEJB应用框架进行详细的研究分析。然后将其应用到一个稻田产业管理系统的开发中。本系统是日本某公司内部使用的系统,主要用于处理与国内外各公司的业务。
第2章 StrutsEJB框架
2.1使用StrutsEJB框架创建J2EE应用程序的步骤
使用StrutsEJB创建J2EE应用程序十分简单,大大加快了WEB应用的开发速度,步骤如下:
◆ 创建一个新的EJBCommand类。
◆ 在struts-config.xml中加入一个路径来调用这个类。
◆ 创建JSP页面。
每一个步骤与Model View Controller(MVC)模型中的元素的对应关系是:EJBCommand是Model,Struts是Controller,JSP页面是View。
第一步,创建一个新的EJBCommand类。
EJBCommand类就是一个Java类。StrutsEJB的会话外观(Session Facade)有两个通用组件——StatelessFacade 和StatefulFacade。这个Facade使业务逻辑开发更容易——不必为每个用例写一个完整的会话bean(或与之相关的接口和DD文件),只需把代码加入到EJBCommand中就可以了。下面是如何写一个EJBCommand类:
◆ 创建一个net.java.dev.strutsejb.EJBCommand的子类。
◆ 覆盖isStateful()方法。
◆ 覆盖executeInStateless或 executeInStateful方法。
见下面的代码,isStateful方法返回一个布尔值,用它来判断EJBCommand是有状态的还是无状态的会话Bean。如果你的代码逻辑不使用任何会话信息,则这个方法返回false。然后StrutsEJB将调用executeInStateless( )方法;如果你想访问会话信息,则返回true。StrutsEJB将调用executeInStateful方法,在这里你能够访问客户端的会话信息。在这个模式中,StrutsEJB会管理会话信息。例如,保存HttpSession中的有状态会话Bean的参数、删除超时队列中的参数、再次执行等等。
public class UserCmd extends EJBCommand {
public void executeInStateless(SessionContext ctx) {
//business logic goes here
final String inMsg = (String) paramDTO.get("inMsg");
resultDTO.put("outMsg", inMsg);
}
public boolean isStateful() {
return false;
}
}
paramDTO和resultDTO都继承java.util.Map接口,这些Maps代表一个DTO(Data Transfer Object),用于在WEB层和EJB层传输值。如果想给一个JSP页面传值,或想接收来自JSP页面的值,那就把他加入到paramDTO和resultDTO中。基于Map的DTO是StrutsEJB框架的关键元素。
第二步,在struts-config.xml中加入一个路径。
在struts-config.xml文件中添加一个路径,EJBCommand才能够被执行。StrutsEJB提供了一个通用的Action类,名字为DefaultAction。如下:
<action path="/User"
type="net.java.dev.strutsejb.web.DefaultAction"
name="form"
scope="request"
parameter="UserCmd">
<forward name="Success" path="/User.jsp"/>
</action>
通常,在Struts编程中,每一个工作流程步骤都有一个Action类。使用StrutsEJB,几乎所有的Actions都由一个的DefaultAction类处理,它可以调用任意的EJBCommand。对于大项目而言,潜在地会有上百个Action类,所以获得较高的工作效率是非常重要的。与一般的Action映射唯一不同的就是,你要在action标签的“parameter”属性中指定EJBCommand类的全名。DefaultAction会检查这个属性,并且执行相对应EJBCommand。
“name”属性指的是ActionForm的“form”。它是DefaultForm的一个实例,与DefaultAction共同合作。form实例在缺省的struts-config.xml文件中是按如下声明的:
<form-bean name="form"
type="net.java.dev.strutsejb.web.DefaultForm"/>
DefaultForm是一个通用的Action Form,它能够接受HTML表单的任意参数,而不需要声明各个域是存储器还是在一个外部xml文件中。如果你想添加一个域,就尽管把它添加到HTML表单里,你可你通过paramDTO和resultDTO访问他。
第三步,用JSTL写JSP页面
我们推荐使用Struts标签写HTML表单(例如:<html:×××>命名空间的标签)。而其他的,我们强烈推荐使用JSTL标签。如下:
<%@ page language="java" session="false"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html:form action="/User ">
<html:text property="dto(inMsg)"/>
<html:submit value="shout"/>
</html:form>
result = <c:out value="${dto.outMsg}"/>
声明中的第2行所使用的是struts-html标签。尽管我们将使用JSTL标签,但是struts-html-el标签比原始的struts-html标签更有用。如果你愿意,你仍旧可以使用原始的struts-html标签和其他的标签库。
怎样访问DTO呢?让我们看看HTML表单中的“property”属性。给每个property都命名为“dto(xxx)”,这样,StrutsEJB的DefaultForm就会自动地get/set这些域值。例如,如果使用一个html:text标签,并且把它的property属性的值设置为“dto(foo)”,DefaultForm就会读取property“foo”,并把获得的值传给paramDTO。执行完EJBCommand以后,存储在resultDTO的所有property将会放到DefaultForm中。当访问HTML表单时,Struts将会读取这些property。
<c:out>标签指的是一个“dto”属性。它是一个由DefaultAction设置的request-scope属性,使得用JSTL EL可以访问resultDTO。由于resultDTO是一个Map类型,EL表达式“${dto.msg}”指的是:从resultDTO中得到“msg”的值。
下面是StrutsEJB的事件顺序:
◆ 用户向Struts发送一个HTTP GET/POST请求。
◆ Struts 指派一个 DefaultForm 去读取请求。
◆ DefaultForm读取所有的命名为“dto(xxx)”的properties。
◆ Struts 指派一个DefaultAction去执行一个 action。
◆ DefaultAction执行在struts-config.xml 文件中所指定的一个EJBCommand。
◆ DefaultAction 从DefaultForm中读取所有的properties,并把他们放在EJBCommand中的paramDTO里。
◆ DefaultAction 执行 EJBCommand。
◆ DefaultAction从由EJBCommand返回的resultDTO中读取所有的properties并且把它们放在DefaultForm 和请求属性“dto”中。
◆ Struts 从DefaultForm 中读取properties,并把他们传递给HTML表单。
JSP页面中的JSTL标签也可以传递一些存储在请求属性“dto”中的值。
第2章 StrutsEJB框架
2.1使用StrutsEJB框架创建J2EE应用程序的步骤
使用StrutsEJB创建J2EE应用程序十分简单,大大加快了WEB应用的开发速度,步骤如下:
◆ 创建一个新的EJBCommand类。
◆ 在struts-config.xml中加入一个路径来调用这个类。
◆ 创建JSP页面。
每一个步骤与Model View Controller(MVC)模型中的元素的对应关系是:EJBCommand是Model,Struts是Controller,JSP页面是View。
第一步,创建一个新的EJBCommand类。
EJBCommand类就是一个Java类。StrutsEJB的会话外观(Session Facade)有两个通用组件——StatelessFacade 和StatefulFacade。这个Facade使业务逻辑开发更容易——不必为每个用例写一个完整的会话bean(或与之相关的接口和DD文件),只需把代码加入到EJBCommand中就可以了。下面是如何写一个EJBCommand类:
◆ 创建一个net.java.dev.strutsejb.EJBCommand的子类。
◆ 覆盖isStateful()方法。
◆ 覆盖executeInStateless或 executeInStateful方法。
见下面的代码,isStateful方法返回一个布尔值,用它来判断EJBCommand是有状态的还是无状态的会话Bean。如果你的代码逻辑不使用任何会话信息,则这个方法返回false。然后StrutsEJB将调用executeInStateless( )方法;如果你想访问会话信息,则返回true。StrutsEJB将调用executeInStateful方法,在这里你能够访问客户端的会话信息。在这个模式中,StrutsEJB会管理会话信息。例如,保存HttpSession中的有状态会话Bean的参数、删除超时队列中的参数、再次执行等等。
public class UserCmd extends EJBCommand {
public void executeInStateless(SessionContext ctx) {
//business logic goes here