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 框架图
7 Struts 框架下应用程序请求流通过的路径。这个处理过程由 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: 不仅包含可以在访问 bean bean 属性时使 用的标记,还包含一些用于消息显示的标记。
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 的参与和支持,最新的 Servlet Jsp 规范总能在 Tomcat 中得到体现。
   由于Java的跨平台特性,基于Java的Tomcat也具有跨平台性。 与传统的桌面应用程序不同, Tomcat 中的应用程序是一个 WAR Web Archive )文件。 WAR Sun 提出的一种 Web 应用程序格式,与 JAR 类似,也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含有 Html Jsp 文件或者包含这两种文件的目录,另外还会有一个 WEB-INF 目录,这个目录很重要。通常在 WEB-INF 目录下有一个 web.xml 文件和一个 classes 目录, web.xml 是这个应用的配置文件,而 classes 目录下则包含编译好的 Servlet 类和 Jsp Servlet 所依赖的其它类(如 JavaBean )。通常这些所依赖的类也可以打包成 JAR 放到 WEB-INF 下的 lib 目录下,当然也可以放到系统的 CLASSPATH 中,但那样移植和管理起来不方便。
   Tomcat 中,应用程序的部署很简单,你只需 WAR 放到 Tomcat webapp 目录下, Tomcat 会自动检测到这个文件,并将其解压。在浏览器中访问这个应用的 Jsp 时,通常第一次会很慢,因为 Tomcat 要将 Jsp 转化为 Servlet 文件,然后编译。编译以后,访问将会很快。另外 Tomcat 也提供了一个应用: manager ,访问这个应用需要用户名和密码,用户名和密码存储在一个 xml 文件中。通过这个应用,辅助于 Ftp ,你可以在远程通过 Web 部署和撤销应用。当然本地也可以。  Tomcat 不仅仅是一个 Servlet 容器,它也具有传统的 Web 服务器的功能:处理 Html 页面。但是与 Apache 相比,它的处理静态 Html 的能力就不如 Apache 。我们可以将 Tomcat Apache 集成到一块,让 Apache 处理静态 Html ,而 Tomcat 处理 Jsp Servlet 。这种集成只需要修改一下 Apache Tomcat 的配置文件即可。
   另外, Tomcat 提供 Realm 支持。 Realm 类似于 Unix 里面的 group 。在 Unix 中,一个 group 对应着系统的一定资源,某个 group 不能访问不属于它的资源。 Tomcat Realm 来对不同的应用(类似系统资源)赋给不同的用户(类似 group )。没有权限的用户则不能访问这个应用。 Tomcat 提供三种 Realm 1 JDBCRealm ,这个 Realm 将用户信息存在数据库里,通过 JDBC 获得用户信息来进行验证。 2 JNDIRealm ,用户信息存在基于 LDAP 的服务器里,通过 JNDI 获取用户信息。 3 MemoryRealm ,用户信息存在一个 xml 文件里面,上面讲的 manager 应用验证用户时即使用此种 Realm 。通过 Realm 我们可以方便地对访问某个应用的客户进行验证。
   在Tomcat中,可以利用Servlet2.3提供的事件监听器功能,来对Application或者Session实行监听。Tomcat也提供其它的一些特征,如与SSL集成到一块,实现安全传输。 还有 Tomcat 也提供 JNDI 支持,这与那些 J2EE 应用服务器提供的是一致的。说到这里要介绍一下通常所说的应用服务器(如 WebLogic )与 Tomcat 有何区别。应用服务器提供更多的 J2EE 特征,如 EJB JMS JAAS 等,同时也支持 Jsp Servlet 。而 Tomcat 则功能没有那么强大,它不提供 EJB 等支持。但如果与 JBoss (一个开源的应用服务器)集成到一块,则可以实现 J2EE 的全部功能。既然应用服务器具有 Tomcat 的功能,那么 Tomcat 有没有存在的必要呢?事实上,在很多中小应用不需要采用 EJB 等技术, Jsp Servlet 已经足够,这时如果用应用服务器就有些浪费了。而 Tomcat 短小精悍,配置方便,能满足我们的需求,这种情况下我们自然会选择 Tomcat
     Tomcat 也可以与其它一些软件集成起来实现更多的功能。如与上面提到的 JBoss 集成起来开发 EJB ,与 Cocoon Apache 的另外一个项目)集成起来开发基于 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 重写了原来的编译系统,现在是基于 autoconf libtool 的,使得 Apache 的配置系统与其他软件包更加相似。 Apache 2.0 在诸如 BeOS OS/2 Windows 等非 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_HOME tomcat 的路径
                 JAVA_HOME j2sdk 的路径

                 Apache是Apache路径

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值