![搞定J2EE:Struts+Spring+Hibernate整合详解与典型案例](https://wfqqreader-1252317822.image.myqcloud.com/cover/194/655194/b_655194.jpg)
1.4 J2EE核心技术
J2EE定义了一个框架和相关的规范,而实现这个框架的具体工具需要第三方厂商来完成,不同的厂商可能实现的方式也不一样,部分厂商可能专注于J2EE架构中的特定组件,比如Tomcat只提供了对JSP和Servlet的支持,而WebSphere和WebLogic应用服务器为整个J2EE规范提供了一个比较完整的实现,它们包含了J2EE定义的多种技术规范。
通常,初学者在学习Java时,会遇到诸如JDBC,JNDI,EJB,JSP和Servlet等技术,这些技术主要应用在哪些方面呢?J2EE核心技术应用的示意图如图1.7所示。
![](https://epubservercos.yuewen.com/23D512/3590305003802101/epubprivate/OEBPS/Images/Figure-0001-07.jpg?sign=1739696801-csCUNZmhZYU7p8kFKlAhUWxGlK8sowjn-0-674c9940bd513a03eea2b89cb2677e0a)
图1.7 J2EE核心技术应用示意图
注:EIS的英文全称是“Enterprise Information System”,中文意思即企业信息系统。
下面将对J2EE所涉及的核心技术进行大概的讲解,目的是使读者了解J2EE的构成和掌握相关的技术。
1.4.1 Servlet
Servlet采用请求响应的工作方式。Servlet技术作为Web服务器功能的增强器,其功能涵盖了从客户端请求相应动态生成文档到保证会话安全,访问后台数据库服务器等。Servlet有自己的生命周期,一般作为Servlet容器或者Web容器中的组件进行管理,每个Servlet都需要实现Servlet接口,其主要的逻辑将集中在service方法中。
Servlet是用Java Servlet API开发的,主要体现在javax.servlet和javax.servlet.http这两个程序包里。这两个程序包里包括了类、接口及框架,它们所封装的功能和属性能为所有Http协议的请求、回应提供通信服务,包括对话处理、post请求和get请求。Servlet是运行在服务器端,用来响应客户端请求的Java代码模块。
★注意★
每个Servlet请求是由同一个线程而不是由一个全新的进程来处理的。
一个Servlet的生命周期由部署Servlet的容器来控制。当一个请求映射到一个Servlet时,该容器执行下列步骤。
● 如果一个Servlet的实例并不存在,Web容器将加载Servlet类,创建一个Servlet类的实例,调用init初始化Servlet实例。
● 调用service方法,传递一个请求和响应对象。
● 如果该容器要移除这个Servlet,可调用Servlet的destroy方法来结束该Servlet。
Servlet的生存期包括加载、实例化、初始化、处理请求及服务结束。
(1)加载和实例化
容器必须先定位Servlet类,在必要的情况下,容器使用通常的Java类加载工具加载该Servlet,可以是从本机文件系统,也可以是从远程文件系统甚至其他的网络服务。容器加载Servlet类后,会实例化该类的一个实例。实例化和加载可以发生在引擎启动的时候,也可以推迟到容器需要该Servlet为客户请求服务的时候。
(2)初始化
Servlet加载并实例化后,容器必须在它能够处理客户端请求前将其初始化。初始化的过程主要是读取配置信息、数据库连接池及其他仅仅需要执行一次的任务。通过调用它的init方法并给它传递唯一的一个ServletConfig对象来完成这个过程。
(3)处理请求
在Servlet被适当地初始化后,容器就可以使用它去处理请求了。每一个请求由Servlet Request类型的对象代表,而Servlet使用ServletResponse返回该请求。这些对象被作为service方法的参数传递给Servlet。在Http请求的情况下,容器必须提供代表请求和响应的HttpServletRequest和HttpServletResponse的具体实现。
(4)服务结束
当service方法中执行的线程执行完或者在服务器定义的一段时间内执行完成后,容器才能够调用destroy方法。因为一旦destroy方法被调用,容器就不会再向该实例发送任何请求。如果容器需要再使用该Servlet,必须创建新的实例。
Servlet 2.5版本增加了对XSD(Xml Schema Definition)的支持,增加了ServletRequest相关的Listener机制,增强了RequestDispatcher和Filter的结合功能,使得RequestDispatcher的功能更加容易实现。
Servlet最新版本是Servlet 3.0,Servlet 3.0在Servlet 2.5基础上增加了若干新特性用于简化Web应用的开发和部署,如:异步处理支持、新增的注解支持、可插性支持。
● 异步处理支持:有了该特性,Servlet线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该Servlet线程。在接收到请求之后,Servlet线程可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。
● 新增的注解支持:用于简化Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得web.xml部署描述文件从该版本开始不再是必选的了。
● 可插性支持:熟悉Struts 2的开发者一定会对其通过插件的方式与包括Spring在内的各种常用框架的整合特性记忆犹新。将相应的插件封装成JAR包并放在类路径下,Struts 2运行时便能自动加载这些插件。现在Servlet 3.0提供了类似的特性,开发者可以通过插件的方式很方便地扩充已有Web应用的功能,而不需要修改原有的应用。
1.4.2 JSP(Java服务页面)
JSP是对HTML的一种扩展,JSP提供的功能大多与Java Servlet类似。Servlet全部是由Java写成并且生成HTML;而JSP通常是大多数HTML代码中嵌入少量的Java代码,JSP的扩展机制还允许开发人员编写自己的标签和相应的实现方法。JSP作为Servlet技术的扩展,简化动态Web内容的传输,由4个关键的组件组成:指令、动作、脚本和标签库。
● 指令是指Web程序员通过编程方式通知支持JSP的Web容器进行定制,比如错误网页或者是定制的标签库或者其他资源。
● 动作则是对网页的动态包含资源或者插件,提交转发,使用JavaBean实例等进行定义与操作。
● 脚本则是支持Java语言的逻辑流,通过特定的标记隔离。
● 标签库包括标准标签库和定制标签库,主要是用于对Web内容显示的一种组件方式的定制。标签库的定义主要由标签句柄类和标签库描述文档组成,句柄类是对定制标签的内容进行定义的一个类,一般要实现Tag接口,标签库描述符则对标签库进行描述,并且与某个句柄类进行相关联。
JSP的运行方式如下。
当浏览器向服务器发出请求时,被请求的JSP首先被Web应用服务器编译成Servlet并执行,然后将所产生的结果作为一个HTML文件传给浏览器。只要在JSP文件中加入一些控制,便可轻易地实现对数据的动态显示。如果该JSP文件没有被修改过,当浏览器再向服务器发出请求时,JSP文件将不会再被编译,而是直接执行已编译好的Servlet。
1.4.3 EJB(企业JavaBean)
EJB组件由容器来管理EJB组件的事务、安全和资源连接问题。前面讲过,EJB主要由三种Bean组成:会话Bean、实体Bean和消息Bean。从EJB 2.0开始,实体Bean就以全新的模型出现,而消息Bean也是在EJB 2.0才引入的。会话Bean主要有有状态与无状态之分,两者的区别仅仅在会话状态的维护上,会话Bean可以作为客户端的状态来理解,客户端是操作与状态的集合。
实体Bean就是对持久化的管理,当然实体Bean可以分为BMP(Bean Managed Persistence)和CMP(Container Managed Persistence),其分歧也就在对持久化的管理方面,这两种实体Bean各有各的好处。BMP由于直接对底层数据库进行持久化操作,所以编码的代价比较高;而CMP则是通过EJB 2.0中引入的EJB QL提供标准接口,屏蔽掉了JDBC驱动的操作,以此通过EJB容器来对持久化进行管理。EJB的调用过程大致上可分为以下几步。
● 根据传入的属性,初始化上下文InitialContext。
● 获取远程的或者本地的Home接口。
● 进行Home.create(),获取远程EJB对象。
● 通过EJB对象调用业务方法,这些业务方法会被EJB实现。
1.4.4 JDBC(Java数据库连接)
Java数据库连接的英文全称是Java Database Connectivity,简称JDBC。与ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDBC对数据库的访问也具有平台无关性,它使用已有的SQL标准并支持与其他数据库连接标准。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。JDBC有如下3种产品组件。
(1)JDBC驱动程序管理器:JDBC驱动程序管理器是JDBC体系结构的支柱。它实际上很小,也很简单,其主要作用是把Java应用程序连接到正确的JDBC驱动程序上,然后退出。
(2)JDBC驱动程序测试工具包:JDBC驱动程序测试工具包为使JDBC驱动程序运行开发人员的程序提供一定的可信度。只有通过JDBC驱动程序测试的驱动程序才被认为是符合JDBC标准的。
(3)JDBC-ODBC桥:JDBC-ODBC桥使ODBC驱动程序可被用作JDBC驱动程序。它的实现为JDBC的快速发展提供了一条途径,其长远目标是提供一种访问某些不常见的DBMS的方法。
目前,比较常见的JDBC驱动程序可分为以下几种。
(1)JDBC-ODBC桥+ODBC驱动程序:JDBC桥利用ODBC驱动程序提供JDBC访问。这种类型的驱动程序最适合于企业网或者是用Java编写的三层结构的应用程序服务器。
(2)本地API:这种类型的驱动程序把客户机API上的JDBC调用转换为Oracle,Sybase,Informix,DB2或其他DBMS的调用。
(3)JDBC网络纯Java驱动程序:这种驱动程序将JDBC转换为与DBMS无关的网络协议,之后这种协议又被某个服务器转换为一种DBMS协议。这种网络服务器中间件能够将它的纯Java客户机连接到多种不同的数据库上,所用的具体协议取决于提供者。这是最为灵活的JDBC驱动程序,有可能所有这种解决方案的提供者都提供适合于Intranet用的产品。
(4)本地协议纯Java驱动程序:这种类型的驱动程序将JDBC调用直接转换为DBMS所使用的网络协议。这将允许从客户机机器上直接调用DBMS服务器,是Intranet访问的一个很实用的解决方法。由于许多这样的协议都是专用的,因此数据库提供者自己将是主要来源。
这里要说明一点:尽管几乎每一个J2EE分布式应用程序都不可能离开数据库与JDBC,但JDBC其实只是J2SE规范中的一部分。
1.4.5 JTA/JTS(Java事务)
为了使应用系统可以访问各种事务监控,JTA定义了一种标准的API,它指定事务管理器与分布式事务中涉及的其他系统组件之间的各种高级接口,这些系统组件有应用程序、应用程序服务器和资源管理器等。JTA功能允许事务由应用程序本身、应用程序服务器或一个外部事务管理器来管理。JTA接口包含在javax.transaction和javax.transaction.xa这两个包中。
JTS事务管理器主要在以下几个地方提供了事务服务:应用服务器、资源管理器、独立应用及通信资源管理器。JTS是CORBA OTS事务监控的基本实现。JTS规定了事务管理器的实现方式,该事务管理器既在高层支持JTA规范,又在底层实现OMG OTS specification的Java映像。
1.4.6 JNDI(Java命名和目录服务)
Java命名和目录服务的英文全称是Java Naming and Directory Interface,简称JNDI。为了便于查找、挂载、卸载及其他操作,JNDI将各个被命名的信元组成树状的目录。JNDI为定位用户、资源与服务提供了一个标准的接口。JNDI作为客户端与命名和目录服务的访问接口,屏蔽了各种命名和目录服务的细节,使得开发人员可以在各种服务之间进行访问。
JNDI由两部分组成:应用程序编程接口和服务供应商接口。应用程序编程接口提供了Java应用程序访问各种命名和目录服务的功能,服务供应商接口提供了供任意一种服务的供应商使用的功能。
JNDI的API主要有javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap;JNDI的SPI在javax.naming.spi中。javax.naming提供了访问命名服务的接口,javax.naming.directory提供了对目录服务的接口,javax.najming.event则是提供对服务的事件机制的支持。
1.4.7 JavaMail(Java邮件服务)
JavaMail使得开发人员可以实现自己的邮件服务,它可以用来建立基于标准的电子邮件客户机,它配置了各种因特网邮件协议,包括SMTP,POP,IMAP和MIME,还包括相关的NNTP,S/MIME及其他协议。JavaMail提供了一套邮件服务器的抽象类,不仅支持SMTP服务器,也支持IMAP服务器。
JavaMail接口包含在javax.mail及其子包中,JavaBeans Activation Framework接口包含在javax.activation包中,核心JavaMail API由7个类组成:Session,Message,Address,Authenticator,Transport,Store及Folder。通过上述类,可以完成发送消息、检索消息、删除消息、认证、回复消息、转发消息、管理附件、处理基于HTML文件格式的消息及搜索或过滤邮件列表等功能,也就是说,常见的电子邮件任务都可以通过JavaMail来实现。
1.4.8 RMI(远程方法调用)
远程方法调用的英文全称是Remote Method Invocation,简称RMI。RMI是一种被EJB使用的更低层的协议,它为分布式计算提供了一种高级的通用解决方案。为了使开发者可以用本地对象调用的语法进行远程调用,它使用了连续序列方式在客户端和服务器端传递数据,将面向对象编程模型扩展到了客户机/服务器系统。RMI在java.rmi及其子包中实现。为了实现位置透明性,RMI使用标准机制——存根和框架。存根是代表远程对象的客户机端对象,它具有和远程对象相同的接口或方法列表。
当客户机调用存根方法时,将执行下列操作。
● 初始化与包含远程对象的服务器端虚拟机的连接。
● 对服务器端虚拟机的参数进行列集(Marshal)并通过RMI基础结构将请求转发到远程对象。
● 等待方法调用结果。
● 散集(Unmarshal)返回值或返回的异常。
● 将值返回给调用程序。
利用RMI编写分布式对象应用程序,开发人员必须完成如下工作。
(1)定位远程对象。
(2)与远程对象通信。
(3)给作为参数或返回值传递的对象加载类字节码。
1.4.9 JMS(Java消息服务)
Java消息服务的英文全称是Java Message Service,简称JMS。JMS是用于和企业消息传递系统相互通信的应用程序接口,其消息传递机制分为两种:发布订阅式(P/S)和点对点式(P2P)。这两种消息的传递机制都实现了异步传递模式,其区别在于前者通过Topic的形式,使得多个Consumer都可以使用,主要是进行了Subscribe;后者则是通过Queue的形式,将Consumer和Producer之间进行了安全连接,使得消息传递只在这两者之间进行。
以前,为了让客户程序访问它们的产品,每个MOM(Message Oriented MiddleWare)供应商都提供专有的API。而现在,用JMS编写的程序能够在任何实现了JMS标准的MOM上运行,这样MOM供应商就不需要再提供专有的API了。
1.4.10 JMX(Java分布式管理)
Java分布式管理的英文全称是Java Management Extensions,简称JMX。它是一种应用编程接口、可扩展对象和方法的集合体,因为它主要是为了解决分布式问题,所以在设计上,它可以跨越各种异构操作系统平台、系统体系结构和网络传输协议,开发无缝集成的面向系统、网络和服务的管理应用。
1.4.11 JACC(Java容器授权合同)
Java容器授权合同的英文全称是Java Authorization Service Provider Contract for Containers,简称JACC。为了将各种授权认证服务器置入J2EE产品中去,它在J2EE应用服务器和特定的授权认证服务器之间定义了一个连接的协约。
1.4.12 JCA(Java连接器体系)
Java连接器体系的英文全称是Java Connector Architecture,简称JCA。它帮助开发者进行不同种类的EIS之间的无缝集成,用一种安全的、事务性的方法连接J2EE应用程序和非J2EE环境。JCA连接器一方面与J2EE应用服务器建立系统级连接,另一方面与访问EIS资源的应用组件建立应用级连接。
JCA规范定义了应用程序和EIS各种级别的接口,描述了如何在应用程序服务器和后端应用程序间部署资源适配器。资源适配器存在于应用程序服务器的地址空间内,实现了允许应用程序服务器和EIS间交互的编程接口。JCA规范可以在同一次消息交换或同一个事务中把消息的发送和处理结合起来,因此利用JCA API的解决方案比利用基于JMS的解决方案在与后端结合方面耦合性要高。
JCA规范中定义了两种级别的编程接口:
● 一种接口是公共客户机接口,任何J2EE组件都可以用这种接口与EIS进行交互。
● 一种接口是系统编程接口,它们只在应用程序服务器内部使用。