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)
图
7
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 Tomcat与Apache的整合
整合
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路径