J2EE架构下系统设计模式

1.1  J2EE 应用模型

J2EE 提供了一个企业级的计算模型和运行环境用于开发和部署多层分布式结构的应用模型。该模型具有重用组件的能力、基于扩展标记语言 (XML) 的数据交换、统一的安全模式和灵活的事务控制。它通过提供企业计算环境所必需的各种服务,使得部署在 J2EE 平台上的多层应用,可以实现高可用性、安全性、可扩展性和可靠性。
1.1.1 J2EE框架
目前,Java 2平台有3个版本,它们是适用于小型设备和智能卡的Java 2平台Micro版(Java 2 Platform Micro Edition,J2ME)、适用于桌面系统的Java2平台标准版(Java 2 Platform Standard Edition,J2SE)、适用于创建服务器应用程序和服务的Java2平台企业版(Java 2 Platform EnterpriseEdition,J2EE)。
J2EE 是一种利用 Java 2 平台来简化企业解决方案的开发、部署和管理相关的复杂问题的体系结构。 J2EE 技术的基础就是核心 Java 平台或 Java2 平台的标准版, J2EE 不仅巩固了标准版中的许多优点,例如 " 编写一次、随处运行 " 的特性、方便存取数据库的 JDBC API CORBA 技术以及能够在 Internet 应用中保护数据的安全模式等等,同时还提供了对 EJB Enterprise JavaBeans )、 Java Servlets API JSP Java Server Pages )以及 XML 技术的全面支持。其最终目的就是成为一个能够使企业开发者大幅缩短投放市场时间的体系结构。
1.1.2 多层分布式结构的应用模型
J2EE 平台采用一个多层次分布式的应用模式。这意味着应用逻辑根据功能被划分成组件,组成 J2EE 应用的不同应用组件安装在不同的服务器上,这种划分是根据应用组件属于多层次 J2EE 环境中的哪一个层次来决定的。图 1 展示了两个多层次 J2EE 应用划分成在下面的表中描述的不同层次。图 1 中表示的 J2EE 应用部分代表了 J2EE 应用组件。
运行在客户机器上的客户层组件
运行在 J2EE 服务器上的 Web 层组件
运行在 J2EE 服务器上的业务层组件
运行在 EIS 服务器上的企业信息系统层软件
如图 1 所示, J2EE 应用可以由三或四个层次组成, J2EE 多层次应用一般被认为是三层应用,因为它们是被分布在三个不同的地点:客户端机器、 J2EE 服务器和数据库或后端的传统系统服务器。三层架构应用是对标准的客户端 / 服务器应用架构的一种扩展,即在客户端应用和后台存储之间增加一个多线程应用服务器。 
 
 
 
 
 
 
 
 图1:多层应用
1.3 J2EE 架构
通常,瘦客户端多层次应用是很难编写的,因为它包括很多行非常难以理解的代码,以处理交易和状态管理,多线程,资源池管理,以及其他复杂的低层次细节问题。基于组件的、与平台无关的 J2EE 应用的开发是很容易的,因为业务逻辑被组织成可重复使用的组件,而且 J2EE 服务器以容器 (Container) 的形式为每种类型的组件提供后台支持。由于你不必自己开发这些服务,你可以专注于解决你面临的业务问题。
1.3.1 容器( container )和服务
组件在部署时被安装在容器之中,是组件和特定平台底层功能之间的接口支持着组件。在 Web ,企业 Bean 或者应用客户端组件能够被执行以前,它必须被组装到 J2EE 应用里,并且被部署到它的容器里。组装流程包括设定 J2EE 应用中的每一个组件以及 J2EE 应用本身在容器之中的设置。容器的设置个性化了 J2EE 服务器对每个组件的后台支持,包括像安全性、交易管理、 Java 命名和目录接口查询,以及远程连接等等。这里是一些重点:
J2EE 安全模式,使你能够配置 Web 组件或企业 Bean ,使系统资源只能被授权的用户访问。
J2EE 交易模式,使你能够指定方法之间的关系,从而组成一个交易,这样交易中的所有方法将被作为一个单元对待。
JNDI 查询服务,为企业中多种命名和目录服务提供统一的接口,这样应用组件就可以访问命名和目录服务了。
J2EE 远程连接模式,管理客户端和企业 Beans 之间的底层通讯。在企业 Bean 被创建后,客户端调用它的方法,就像它在同一个虚拟机上一样。
实际上, J2EE 架构提供可配置的服务,意思是在同一个 J2EE 应用中的应用组件可以根据他们部署的位置不同,表现不同。一个企业 Bean 可以通过不同的安全设置,是它在一个生产系统中获得一种层次的数据库数据访问,而在另一个生产系统中,则获得另一种数据库访问权限。
容器还管理着不可配置服务,如企业bean和Servlet的生命周期,数据库连接资源池,数据持续性(persistence),以及J2EE API中描述的访问J2EE平台的API。 尽管数据持续性机制是一个不可配置服务, J2EE 架构允许你在需要比缺省的容器管理的持续性机制更多的控制时,用你的企业 Bean 实现中的相应的代码覆盖原有的容器管理的持续机制。例如,你可以使用 Bean 管理的持续性机制来实现你自己的搜索方法,或创建个性化的数据库缓存。
1.3.2 容器类型
在部署过程之中, J2EE 应用组件被安装在如下类型的 J2EE 容器中。本文中涉及的 J2EE 组件和容器参见图 5
企业JavaBeans(EJB)容器,为J2EE应用管理着所有的企业Beans。企业Bean和它们的容器运行在J2EE服务器上。
Web 容器,为 J2EE 应用管理着所有的 JSP 页面和 Servlet 组件。 Web 组件和它们的容器运行在 J2EE 服务器上。
应用客户端容器,为 J2EE 应用管理着所有的应用客户端组件。应用客户端组件和它们的容器运行在客户端机器上。
applet 容器,是 Web 浏览器和 Java 插件的组合,运行在客户端机器上。
                    
 
 
 
 
 
 
 
 
5 J2EE 服务器和容器
1.3.3 包装
J2EE 组件是单独包装的,为部署而捆绑到 J2EE 应用中。每个组件,其相关的文件如 GIF HTML 文件,或者服务器端应用类,以及部署描述,被集成一个模块并添加到 J2EE 应用中。 J2EE 应用是由一个或多个企业 Bean Web ,或应用客户端组件模块组成的。最终企业解决方案可以使用一个 J2EE 应用或根据设计需要由两个或更多的 J2EE 应用组成。
一个 J2EE 应用以及它的每一个模块都有它自己的部署描述。部署描述是一个 XML 文本文件,带有 .xml 后缀,描述组件的部署设置。一个企业 Bean 的部署描述,例如,声明交易属性,和企业 Bean 的安全认证。由于部署描述的信息是可以声明的,这样它可以在无需修改 Bean 的源代码的情况下,进行修改。在运行时, J2EE 服务器读取部署描述,并依次对组件进行操作。
J2EE应用以及相关的模块是在一个Enterprise Archive(EAR)中发送的。EAR文件是一个标准的JAR文件,以.ear后缀结尾。在GUI版的J2EE SDK应用部署工具集中,你先创建一个EAR文件,在添加JAR和WAR到EAR中。如果你使用命令行打包工具,则先创建JAR和WAR文件,然后创建EAR文件。J2EE SDK工具:
每个 EJB JAR 文件包含它的部署描述,相关文件和企业 Bean .class 文件
每个应用客户端 JAR 包含它的部署描述,相关文件和应用客户端的 .class 文件
每个 WAR 文件包含它的部署描述,相关文件和 servlet .class 文件以及 JSP 页面的 .jsp 文件
使用模块和 EAR 文件使使用一些相同的组件组装多个不同的 J2EE 应用成为可能。无需额外的编程,只是把不同的 J2EE 模块组装到 J2EE EAR 文件中。
1.4 J2EE API
Java 2 平台标准版( J2SE SDK 在运行 J2EE SDK 时是必需的,它为编写 J2EE 组件提供核心 API ,核心开发工具,以及 Java 虚拟机。下面介绍科研管理系统中所涉及到的 API
1.4.1 企业 JavaBeans 技术 2.0
一个企业 Bean 是一段包含域和方法的代码体,用于实现业务逻辑的一个模块。你可以认为企业 Bean 是一个构建模块,可以单独使用或与其他企业 Beans 一起在 J2EE 服务器上执行业务逻辑。
由三种类型的企业 Bean Session Bean ,实体 Beans ,和消息驱动 Beans ,这些在业务组件中描述过。有了实体 Beans ,你无需编写任何 SQL 代码或直接使用 JDBC API 执行数据库访问操作。 EJB 容器替你处理这些。当然,如果你不管因为任何原因,覆盖了却省的容器管理持续性机制,你将需要使用 JDBC API 。同样,如果你选用 Session Beans 访问数据库,你必须使用 JDBC API
1.4.2 JDBC 2.0 API
       JDBC 是为 java 语言定义的一个 SQL 调用级( CLI )界面,也就是说其中心在于执行基本的 SQL 声明和取回结果。在此基础上可以定义更高层次的 API ,其中的接口包括直接将基本表与 JAVA 中的类相对应,提供更多的通用查询的语义树表示,以及 JAVA 语言的嵌入式 SQL 语法等。
1.4.3 Java Servlet 技术 2.3
Java Servlet 技术为你定义 HTTP 专用的 servlet 类。一个 Servlet 类扩展了服务器的能力,这个服务器存放着应用,而应用是以请求 - 响应编程模式被访问的。尽管 Servlet 可以响应任意形式的请求,但是它通常被用于扩展 Web 服务器存放的应用。
1.4.4 JavaServer Pages(JSP) 技术 1.2
JSP 页面技术是你能够在基于文本的文件中结合小段的 Java 编程语言代码和静态内容。一个 JSP 页面是一个基于文本的文件,它包含两种类型的文本:静态模板数据,它可以表示为任何基于文本的格式,如 HTML WML XML JSP 元素,决定这个页面如何构造动态内容。
1.4.5 JavaMail 技术 1.2
很多互联网应用需要发送邮件进行确认,所以 J2EE 平台包含了与 JavaMail 服务提供商配合使用的 JavaMail API ,这样,应用组件可以使用它发送邮件。 JavaMail API 包含两个部分:一个是应用层接口,应用组件使用它发送邮件;一个服务提供商接口。
1.5 MVC 设计模式
MVC设计模式起源于Smalltalk语言,它由以下三个部分组成:模型(model),视图(view),控制器(Controller)。
Model : 模型指的是真正完成任务的代码,包含应用系统的核心功 能表示一个应用系统的数据,并且包含访问、维护和管理这些数据的逻辑。所有属于应用系统持久状态的数据都应该保存于模型对象里。模型提供的服务必须足够适用于不同的终端。一个模型聚集了相关的数据和操作,以提供 一个详细而精确的服务 ; 这些被封装在操作中的抽象事物的功能被模型化。一个模型的接口提供了访问和更新模型状态,执行封装在模型中的复杂进程 的方法。模型服务被控制器访问,用于查询或更改模型的状态。当模型状态 发生变化时,模型会通报给视图。对大多数 Web 应用程序而言,功能比界面 感觉更重要。在模型同界面分离的情况下,代码即可实现可管理性和可重用 性。例如,在一个保险应用程序中,模型就是处理计算保险费和同数据库交互的那些业务代码。模型通常也被称作业务逻辑。
View : 视图表示模型的状态,是应用系统的外观,当模型发生改变时, 视图也将随之改变,以维持系统数据的一致性。在 MVC 模式下,通常的设计 前提是界面任务较小。当然视图也应该具有一定的功能性并遵守可用性的约 束,但视图界面不应当处理数据。事实上,视图的每一部分都只能包含采集 数据的逻辑,并把采集到的数据传递给设计模式中的其他组成部分进行处 理。
Controller : 控制器是联系模型与视图之间的纽带,控制模型和视 图之间的交互过程。它获取并翻译用户输入的动作,指定执行该动作的模型, 或者根据用户的输入和执行的结果来选择下一个视图。
MVC 通过建立一个 订购 / 通知 协议来分离视图和模型。视图必须保证它的显示正确地反映了模型的状态。一旦模型的数据发生变化,模型将通知有关的视图,每个视图相应地得到刷新自己的机会。这种方法可以让一个模型提供不同的多个视图表现形式,也能够为一个模型创建新的视图而无须重写模型。
1.5.1 MVC 的优点
(1) 因为视图与模型分离,而且模型与视图之间没有直接依赖性,所以用户界面可以同时显示同一数据的多个视图。例如, Web 应用程序中的多个页面可以使用同一模型对象。变化一传播机制可以确保所有相关的视图及时 得到模型数据变化,从而使所有关联的视图和控制器做到行为同步。
(2) 视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换。
(3) 模型的可移植性。因为模型是独立于视图的,所以可以把一个模型独立地移植到新的平台工作。需要做的只是在新平台上对视图和控制器进 行新的修改。
(4) 潜在的框架结构。可以基于此模型建立应用程序框架,不仅仅是 用在设计界面的设计中。
1.5.2 MVC 的缺点
(1) 增加了系统结构和实现的复杂性。 MVC 模式引入了新的间接级别, 因此稍微增加了解决方案的复杂性。它还增加了用户界面代码的事件驱动特 性,调试用户界面代码会变得更加困难。
(2) 视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
(3) 视图对模型数据的低效率访问。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据 . 对未变化数据的不必要的频繁访 问,也将损害操作性能。
(4) 频繁更新的成本。将模型与视图分离并不意味着模型的开发人员可 以忽略视图的特性。例如,如果模型发生频繁更改,则它可能向视图发出大 量更新请求。一些视图 ( 如图形显示 ) 的显示可能需要一定时间。因此,视 图可能滞后于更新请求。因此,在对模型进行编码时牢记视图是很重要的。 例如,模型可以将多个更新作为单个通知发送到视图。
                               模型     
            查询状态
                     向视图通知模型          在模型的公共
                       状态中的改变                    API中调用方法
 
    视图         选择视图               控制器
            用户动作/命令
                      方法调用
        事件
图6     MVC的体系结构
1.6 Struts对MVC实现
模型( The Model
Struts框架没有提供特定的模型组件。
视图( The View
Struts 框架中 视图组件对应于一个简单的 JSP 文件,这个 JSP 文件包含了 Struts 定义的标签,几个 JSP 的标签是 JSP 文件中的重点。这些标签在 Struts 框架中定义,它使 struts 应用项目和控制器之间实现松耦合。
控制器( The Controller
控制器是Struts框架中的中枢,它由 org.apache.struts.action.ActionServlet 这个servlet来贯彻和执行的。这个 org.apache.struts.action.ActionServlet 接收所有客户端的请求,并把请求委派到指定的Action类(用户扩展自 org.apache.struts.action )。ActionServlet委派请求是基于客户端传入的URI。一旦Action类完成处理,ActionServlet根据Action返回的键值来决定在什么视图中显示Action的类处理结果。ActionServlet类似于一个创建Action对象的工厂,由Action对象去执行应用中实际的业务逻辑。控制器是Struts框架中最重要的部分。
1.6.1 Struts的运行过程
下面是一幅和MVC模式对应的STRUTS框架图
 视图(view1)                                   
                                              Action1
                                                   
                                              Action2
                   ActionServlet              Action3
                     (控制器)
                                              Action4
                                                  
视图(view2)                                          模型(Model)
 
               STRUTS框架图
7Struts框架下应用程序请求流通过的路径。这个处理过程由5个基本的步骤组成。
下面是处理步骤的描述。
1由显示视图产生一个请求。
2. 请求被ActionServlet(控制器)接收,它在struts-config.xml文件中寻找请求的URI,找到对应的Action类后,Action类执行相应的业务逻辑。
3 Action类执行建立在模型组件基础上的业务逻辑,模型组件是和应用程序关联的。
4. 一旦Action类处理完业务逻辑,它把控制权返回给ActionServlet。,Action类提供一个键值作为返回的一部分,它指明了处理的结果。ActionServlet使用这个键值来决定在什么视图中显示Action的类处理结果。
5. ActionServlet把Action类的处理结果传送到指定的视图中,请求的过程也就完成了。


 
                 HttpServlet                                          FrowardConfig
   <<front controller>>
org.apache.struts.action.ActionServlet                    org.apache.struts.action.ActionForWard
 
 
 
  <<dispatcher>>                                                     ActionConfig
 org.apache.struts.action.RequestProcessor                  org.apache.struts.action.ActionMapping
 
 
                      Serializable
           <<view helper>>                                <<request handler>>
   org.apache.struts.action.ActionForm                               org.apache.struts.action.Action
 
图8 Struts中MVC实现
 
8中各个类的语义
1. ActionServlet类:实现控制器,Struts必需的配置在ActionServlet.init()方法中加载。ActionServlet将所有的输入请求委托给RequestProcessor.
2. RequestProcessor类:分配器,所有输入的请求都被控制器委托给分配器(dispatcher).
3. ActionForm类:存储表单数据,由ActionForm派生出来的对象用于存储请求对象中的参数,因此它们和用户是紧密耦合的。
4. ActionForward类:ActionForward对象是配置对象。这些配置对象有唯一的标识符,以使它们根据有意义的名称进行寻找。ActionForward对象封装提交的URL路径,它被请求处理程序用来标识目标视图。
5. ActionMapping类:它提供了引入的请求和相应的请求处理程序之间的映射。
6.Action类:请求处理程序。Action类的子类作为适配器用于引入的请求和模型之间。Action类的子类是为每个请求单独创建的。Action的基类提供了访问与框架相关的资源的公共函数,以及保存由它的子类的exectue(…)方法进行检查而得到错误的方法。
1.6.2 Struts的主要组件:
1.6.2.1 控制器对象
控制器语义有ActionServlet。控制器语义提供了处理所有客户请求的中心位置。这就为控制器层提供了一个清楚的工作分配情况,控制器层主要的工作是处理试图和导航管理、将模型访问和操作交给有特定请求的请求处理程序(Command对象[Gof])。所有引入的请求被映射到部署描述符的中心控制器上。
1.6.2.2 分配器对象
RequestProcessor作为一个分配器运行,并通过实例化(或重用)一个请求处理和对应的表单bean来处理客户机请求。创建的错误或是表单bean和请求处理程序抛出的异常(由RequestProcessor处理),影响了RequestProcessor的视图管理功能。表单bean帮助RequestProcessor存储表单数据和分段传输视图需要的中间模型数据,RequestProcessor使用<action>声明实例化特定请求的请求处理程序。
1.6.2.3请求处理程序
Action类的子类作为适配器用于引入的请求和模型之间。请求最初由RequestProcessor截获,RequestProcessor则实例化一个对应的请求处理程序。这个从Action类继承而来的对象(也称为请求处理程序)是为每个请求而特别创建的。客户机请求封装请求URI中所需的动作作为servlet路径,该路径信息随后有分配器(RequestProcessor)提取,从而创建相应的请求处理程序来处理程序实例。命令模式将URI从请求处理程序中分离出来。
1.6.3 Struts的配置文件struts-config.xml
Struts 的核心是控制器ActionServlet,而ActionServlet的核心是配置文件struts-config.xml,该配置文件的主要作用是建立控制器与模型之间的联系。它描述了控制器将客户请求映射到对应处理的法则,同时还定义了用户输入数据与ActionFor。组件的对应映射关系。此外,该配置文件的另一个作用是将逻辑名映射到物理路径,使得物理路径与程序路径无关,整个系统导航使用逻辑名在struts-config.xml中完成。
这种在配 置文件中完成业务逻辑控制的方法主要有以下几个优点:先,应用的所有页面的导航定义都集中在一个分等级的文本文件中,通过此配置文件即可迅速把握整个系统的脉络;第二,网页设计人员在修改网页时无需遍历Java代码来理解应用的业务逻辑,而当业务逻辑发生改变时,业务逻辑开发者也只需在struts-config.xml中做出相应的调整和修改,而无需重新编译代码。在大型的Web应用系统中,这种管理页面逻辑的方式无论是在系统前期的开发过程,还是后期的维护与升级阶段都显示出了方便性和有效性。
struts-config.xml的正文部份由八个元素组成,下面将对系统中涉及的元素的功能与使用方法举例阐明。
1.6.3.1 定义ActionForm
ActionServlet使用ActionForm来保存请求参数,这些Bean的属性名称与HTTP请求参数中的名称相对应,控制器将请求参数传递到ActionFormBean的实例中,然后将这个实例传送到Action类。Struts的配置文件struts-config.xml提供了一个<form-beans>元素用于统一管理系统中所有的ActionForm Bean。每个ActionForm Bean都由一个相应的<form-bean>元素创建。在运行时,控制器通过调用适当的ActionForm Bean来确定被创建的ActionForm对象及特性。下面是项目中一个针对常规ActionForm的<form-bean>元素配置:
<form-beans>
<form-bean name="userInfoForm"            type="aiai.keyan.manage.user_Manage.pursuerInfoBean" />
</form-beans>
其中,属性name是表单bean在相关作用域的名称,它用于将ActionFormBean与ActionMapping进行关联;而属性type是类的完全限定名。
1.6.3.2 定义全局转发
在常见的Web应用中,多数URI都与应用中的物理文件直接映射,这在应用开发的初级阶段显得较为容易。但是,在应用开发的后期或维护阶段,应用的逻辑通常会发生改变,这时就必须更新整个应用,如果遗漏了某部分,就会产生异常更新。这一点给应用的后期开发者和维护人员造成了不小的困难。为了解决这一难题,在Struts应用中,开发人员将逻辑名映射到物理地址,在应用中使用逻辑名实现系统导航,这就使得应用的物理地址与程序地址无关。而元素<global-forwards>就是用于实现这个功能。这个元素可以包含任意个<forward/>子元素,每一个子元素对应一个逻辑名与一个物理地址的映射。当系统的逻辑发生改变时,开发人员只需修改相应<forward/>中的映射关系即可。如下所示:
<global-forwards>
<forward name="forStep1"
path="/researching/datainput/step1.jsp" />
</global-forwards>
上述代码是项目的配置文件中的一部分。其中,属性name表示全局转发的逻辑名,path表示目标URI的物理路径。除了可 以 在<global-forwards>元素中部署全局转发外,开发人员除还可以在<action>元素中部署局部转发, 局部转发仅针对对应的ActionMapping有效。
1.6.3.3 定义Action映射
<Action -Mapping>元素的作用在于帮助开发人员进行框架内部的流程控制。该元素可以包含任意个<action />子元素。每一个子元素将一个请求URI路径映射到对应的Action类,并且将Action类与对应ActionForm bean相关联。ActionServlet在内部使用这些映射,并将控制转移到特定的Action类实例。所有Action类使用perform()方法实现特定的业务逻辑,然后返回一个ActionForward对象,其中包括响应转发的目标资源名称。下列代码截取自项目的配置文件:
<action-mappings>
<action name="userInfoForm"  type="aiai.keyan.manage.user_Manage.Struts.userInfoAction" validate="true"
input="/menage/user/register1.jsp"
scope="request" path="/register1" />
</action-mappings>
其中子元素<action>的属性path表示Action类的相对路径,name表示与指定操作关联的Action Bean的名称,type表示连接到本映射的Action类的全称,scope表示与指定Action对应的ActionForm Bean的作用域,input表示输入表单的路径和发生输入错误时系统应返回的页面。在<action-mappings>元素中还可以使用<forward>子元素定义资源的逻辑名称,该资源是Action类的响应要转发的目标。其中<forward>的属性name表示Action类访问ActionForward时所用的逻辑名,path表示响应转发的目标资源的路径。
1.6.4 Struts的自定义标记库
Struts 提供了一组可扩展的自定义标记库(Taglib),采用这些标记库,可以帮助开发人员简化创建用户界面的过程。目前 Struts提供了四种基本自定义Taglib以及两种附加Taglib .
struts-bean taglib:不仅包含可以在访问beanbean属性时使用的标记,还包含一些用于消息显示的标记。
struts-html taglib:不仅包含用于创建Struts输入表单的标记,而且包含其它通常用来创建动态HTML用户界面或表格的标记。
struts-logic taglib:该库所包含的标记通常用于管理输出文本的条件生成、循环使用对象集合以重复生成输出文本以及应用程序流管理。
struts-template taglib:该库包含的标记可用作创建动态JSP模板,所有采用同一模板的JSP页面都拥有一个公共的外观或共同的格式。
T iles 插件:除了替代Template的基本模板功能外,还增加了布局定义、虚拟页面定义和动态页面生成等功能。Tiles强大的模板功能能够使页面获得最大的重用性和灵活性,此外,结合Tiles配置文件中的页面定义Action的转发逻辑(即将一个Action转发到一个在Tile:配置文件中定义的虚拟页面),可以减少页面的数量,从而简化JSP开发。
Nested:该标记库的作用在于让上述的基本Struts自定义标记库的功能能够嵌套应用于上下文,发挥更大的作用。
 
2.7 WEB服务器的搭建与集成
2.7.1 jsp,Serlvet容器Tomcat
      Tomcat是一个免费的开源的Serlvet容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache,Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的ServletJsp规范总能在Tomcat中得到体现。
   由于Java的跨平台特性,基于Java的Tomcat也具有跨平台性。与传统的桌面应用程序不同,Tomcat中的应用程序是一个WARWeb Archive)文件。WARSun提出的一种Web应用程序格式,与JAR类似,也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含有HtmlJsp文件或者包含这两种文件的目录,另外还会有一个WEB-INF目录,这个目录很重要。通常在WEB-INF目录下有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的Servlet类和JspServlet所依赖的其它类(如JavaBean)。通常这些所依赖的类也可以打包成JAR放到WEB-INF下的lib目录下,当然也可以放到系统的CLASSPATH中,但那样移植和管理起来不方便。
   Tomcat中,应用程序的部署很简单,你只需WAR放到Tomcatwebapp目录下,Tomcat会自动检测到这个文件,并将其解压。在浏览器中访问这个应用的Jsp时,通常第一次会很慢,因为Tomcat要将Jsp转化为Servlet文件,然后编译。编译以后,访问将会很快。另外Tomcat也提供了一个应用:manager,访问这个应用需要用户名和密码,用户名和密码存储在一个xml文件中。通过这个应用,辅助于Ftp,你可以在远程通过Web部署和撤销应用。当然本地也可以。 Tomcat不仅仅是一个Servlet容器,它也具有传统的Web服务器的功能:处理Html页面。但是与Apache相比,它的处理静态Html的能力就不如Apache。我们可以将TomcatApache集成到一块,让Apache处理静态Html,而Tomcat处理JspServlet。这种集成只需要修改一下ApacheTomcat的配置文件即可。
   另外,Tomcat提供Realm支持。Realm类似于Unix里面的group。在Unix中,一个group对应着系统的一定资源,某个group不能访问不属于它的资源。TomcatRealm来对不同的应用(类似系统资源)赋给不同的用户(类似group)。没有权限的用户则不能访问这个应用。Tomcat提供三种Realm1JDBCRealm,这个Realm将用户信息存在数据库里,通过JDBC获得用户信息来进行验证。2JNDIRealm,用户信息存在基于LDAP的服务器里,通过JNDI获取用户信息。3MemoryRealm,用户信息存在一个xml文件里面,上面讲的manager应用验证用户时即使用此种Realm。通过Realm我们可以方便地对访问某个应用的客户进行验证。
   在Tomcat中,可以利用Servlet2.3提供的事件监听器功能,来对Application或者Session实行监听。Tomcat也提供其它的一些特征,如与SSL集成到一块,实现安全传输。还有Tomcat也提供JNDI支持,这与那些J2EE应用服务器提供的是一致的。说到这里要介绍一下通常所说的应用服务器(如WebLogic)与Tomcat有何区别。应用服务器提供更多的J2EE特征,如EJBJMSJAAS等,同时也支持JspServlet。而Tomcat则功能没有那么强大,它不提供EJB等支持。但如果与JBoss(一个开源的应用服务器)集成到一块,则可以实现J2EE的全部功能。既然应用服务器具有Tomcat的功能,那么Tomcat有没有存在的必要呢?事实上,在很多中小应用不需要采用EJB等技术,JspServlet已经足够,这时如果用应用服务器就有些浪费了。而Tomcat短小精悍,配置方便,能满足我们的需求,这种情况下我们自然会选择Tomcat
     Tomcat也可以与其它一些软件集成起来实现更多的功能。如与上面提到的JBoss集成起来开发EJB,与CocoonApache的另外一个项目)集成起来开发基于Xml的应用,与OpenJMS 集成起来开发JMS应用,除了我们提到的这几种,可以与Tomcat集成的软件还有很多。
配置Tomcat虚拟目录,为了使得Tomcat即可以实时对开发工具的修改进行监测,以达到与开发工具实时同步数据。可以在不重启服务器的情况下对项目进行修改。这是非常重要的由于在一台服务器上可能运行这不止一个的WEB项目,在新加项目时不可能让服务器重启,因此必须配置虚拟目录。在{TOMCAT_HOME}/conf/server.xml中的<Host></Host>之间加上
<Context path="dir1"
docBase="D:\web"  
reloadable="true" crossContext="true" >
</Context >
其中:
path: web应用的context路径。catalina将每个URL的起始和context path进行比较,选择合适的web应用处理该请求。特定Host下的context path必须是惟一的。如果context path为空字符串(""),这个context是所属Host的缺省web应用,用来处理不能匹配任何context path的请求。
DocBase:该web应用的文档基准目录(Document Base,也称为Context Root),或者是WAR文件的路径。可以使用绝对路径,也可以使用相对于context所属的Host的appBase路径。
Reloadable: 如果希望Catalina监视/WEB-INF/classes/和/WEB-INF/lib下面的类是否发生变化,在发生变化的时候自动重载web application,设为true。这个特征在开发阶段很有用,但也大大增加了服务器的开销。因此,在发布以后,不推荐使用。但是,你可以使用Manager应用在必要的时候触发应用的重载。
CrossContext:如果想在应用内调用ServletContext.getContext()来返回在该虚拟主机上运行的其他web application的request dispatcher,设为true。在安全性很重要的环境中,设为false,使得getContext()总是返回null。缺省值为false。
2.7.2 HTTP服务器Apache2.0
Apache HTTP服务器被设计为一个强大、灵活的能够在多种平台上及不同的环境下工作的服务器。不同的平台和不同的环境经常产生不同的需求,或是会为了达到同样的最佳效果而采用不同的方法。Apache凭借它的模块设计很好的适应了大量不同的环境。这一设计使得网站管理员能够在编译时和运行时凭借载入不同的模块来决定服务器的不同附加功能。
Apache可以在混合多进程、多线程模式下运行,使很多(但不是全部的)配置的可扩缩性得到改善。Apache2.0重写了原来的编译系统,现在是基于autoconflibtool的,使得Apache的配置系统与其他软件包更加相似。Apache 2.0在诸如BeOSOS/2Windows等非Unix平台上有了更好的速度和稳定性。 随着平台特定的multi-processing modules(MPMs)和 Apache Portable Runtime (APR)的引入,Apache在这些平台上的指令由它们本地的API指令实现。 避免了以往使用POSIX模拟层造成的bug和性能低下。
2.7.3 TomcatApache整合
整合Apache有两个目的
1. 把静态和动态的内容分别有两个不同的服务器承担
2.达到简单的负载均衡
修改Uri mapping的内容即可实现分流
如:
# Uri mapping 
[uri:/*.*] 
改成
# Uri mapping
[uri:/*.do]
[uri:/*.jsp]
第一步 把mod_jk_2.0.47.dll拷贝到{Apache}\modules文件夹中。
第二步 在{TOMCAT_HOME}\conf中新建一个workers.properties文件内容如下
#####--begin--########
 workers.tomcat_home={TOMCAT_HOME} #mod_jk模块知道Tomcat
 workers.java_home={JAVA_HOME}       #mod_jk模块知道j2sdk
 ps=\
 worker.list=ajp13                       #模块版本
 worker.ajp13.port=8009                  #工作端口
 worker.ajp13.host=localhost               #主机名称
worker.ajp13.type=ajp13                 #类型
 worker.ajp13.lbfactor=1                  #代理数
######---end---#######
第三步 打开{Apache}\conf\httpd.conf 在文件末尾添加如下内容
########-beging--########
<VirtualHost localhost>                                              
ServerAdmin hua@mzh.com                #apache注册的信息
DocumentRoot D:\Web                     
#tomcat虚拟目录中docBase相同
ServerName localhost                        #主机名称
ErrorLog logs/robornet_home_log.txt    #日志                           
CustomLog logs/robornet_Custom_log.txt common                 
JkMount /* ajp13         #目录中的以下文件由tomcat处理                        
JkMount /*.jsp ajp13   
JkMount /*.do ajp13                                           
JkMount /*.gif ajp13 
JkMount /*.jpg ajp13   
JkMount /*.css ajp13
JkMount /*.js ajp13    
</VirtualHost> 
########-end--########
 
########-beging--########
LoadModule jk_module modules/mod_jk_2.0.47.dll
#装载模块,用于处理连接(对上一行的注释,下同)
JkWorkersFile "{ TOMCAT_HOME }/conf/workers.properties"
#设置模块的工作文件
JkLogFile "{ TOMCAT_HOME }/logs/mod_jk2.log"
 #设置模块工作的日志文件,Tocmat启动时会自建
JkLogLevel info
######---end---###########
其中:TOMCAT_HOMEtomcat的路径
                 JAVA_HOMEj2sdk的路径

                 Apache是Apache路径


posted on 2007-03-09 00:52 金家寶 阅读(2363) 评论(0)  编辑  收藏 所属分类: J2EE概念理论性文摘


只有注册用户登录后才能发表评论。


网站导航: