1.1 瘦客户的连接
瘦客户(例如网络浏览器或者无线浏览器)代表有兴趣查看网页的人们。网络服务应该执行网页请求所需要的任何必要处理,例如执行B2C传输和显示一个定购确认页。
为了实现这个,开发者用JavaServer页(JSP)技术编写动态网页。JSP组件是一个动态页面技术,它能基于后端数据处理结果成内容(通常是HTML和XML)。它们在一个容器的可管理的环境下运行,它提供JSP组件需要的服务,诸如解释它们成可执行代码。
JSP组件作为进入后端商业逻辑层的前端“呈现”界面,可能用各种不同的方法来实现(例如EJB,普通Java对象,或者普通的JavaBeans)。它们随后产生结果,典型的是HTML或XHTML(一个XML兼容的HTML版本)。
JSP组件代表一个用户交互界面,而不是一个其它系统能够调用的程序接口。例如,一个股票报价服务可能被一个技术股票报价平均值的网络服务进行程序调用。相同的后端股票报价服务可能用JSP技术产生网络页面返回给终端用户股票报价。
图5显示了JSP组件的所处的角色。
图 5 JSP组件响应一个网络请求
注意到在上下文中使用JSP组件的方法是描述性的但是不是说明性的。开发者也可能使用Java servlets(后面讨论)来产生相同的结果。
1.2 肥客户的连接
一些连接到网络服务的客户被称作肥客户。例如,在一个公司内部LAN拓补下,诸如下载次数、安全和异构技术变得不是很重要的事情。用户界面的响应能力和功能可能更加重要,特别是当应用程序建立在一个常用的基础上,例如内部调用中心应用程序。
一个肥客户能够以不同的方式连接网络服务。例如,它能使用诸如UDDI,WSDL,SOAP和ebXML的技术。这个范例是最小效率的,因为客户和服务器双方都是相同的开发组开发的,它不需要什么XML的传输和处理。
一个更高效的方法是使用诸如RMI-IIOP(Java Remote Method Invocation over the Internet Inter-ORB Protocol)更高效的协议。OMG的IIOP是用于EJB组件间通讯的标准协议,肥客户可以利用这个来直接连接EJB层。
2 实现网络服务
现在为止,我们已经讲到了我们的网络服务如何连接各种类型的客户端。下一步,我们看看如何实现网络服务的内部。
2.1 数据解释和传输(Data Translation and Transformation)
在进入一个网络服务前,我们首先需要克服的困难是建立一个界面层来解释接收的XML数据为一个可以被我们的网络服务处理的格式,然后解释结果为XML格式给客户。一个开发者因此需要稳健的机制来解析XML,把它们绑定到Java的对象,生成XML,以及转换各种XML格式。有时,因为我们的应用程序支持不同的界面,例如来自B2B合作者SOAP,来自网络浏览器的HTML,来自无线浏览器的WML都需要同一套服务,我们需要不同的程序来为各个客户提供不同的服务接口以便处理与不同客户端环境相联系的不同语义。
2.1.1 JAXP
Java API for XML Processing是一个Java的XML解析的工业标准API。它有SAX (Simple API for XML) 和 DOM (Document Object Model),也有一个可挂接的XSLT (XML Stylesheet Language Transformations) 引擎接口。这些形成解析和处理XML文档的基础。当这些API对于网络服务来说有些原始,它们代表了目前发布了的处理XML的最佳软件。JAXP提供给我们Java中全部功能的访问、修改和建立XML文档的API,它是我们的网络服务接口中最基本的API.
详细信息请看:
http://java.sun.com/xml/tutorial_intro.html
http://java.sun.com/xml/xml_jaxp.html
2.1.2 JAXB
Java API for XML Binding是将要制订的把XML文档和Java对象相互转换的规范。使用JAXB,你能利用后台的EJB层自动转换XML文档为Java对象。你也可以从EJB层获得对象并转换为XML,它可以被返回给商业伙伴。
JAXB接口提供比DOM和SAX高层的处理XML文档的方法。这个规范允许XML schema和Java类的相互转换,提供一个简单的办法来转换XML文档为Java对象实例或者反之。这也比一次处理一个标签要简单得多。
2.1.3 XSLT
从商业伙伴来的XML文档可能采用的不是相应的内部使用的框架(Schema)。例如一个商业伙伴可能使用术语“OrderNum”,而我们使用“OrderID”。
相反,我们常需要根据发出请求的不同的客户把一个返回结果表达成不同的格式。例如,一个商业伙伴的调用可能需要SOAP形式的返回结果,而浏览器用户需要XHTML形式的结果。在更复杂的情况下,我们需要支持更多的格式,诸如无线设备需要的WML,声音响应系统需要的VoiceXML。这需要我们有一套机制来转换基本的XML响应为不同的XML格式以为本系统提供不同的接口。
XML Stylesheet Language Transformations (XSLT)是把转换XML文档从一个schema转换为另一个的机制。一个样式表(Stylesheet)规定了一系列模式匹配规则并把它用于递归的类似于DOM范例的树遍历中。一个XSLT样式表语法表达力丰富,包含完整的循环、条件、数学运算指令集以及类似函数的结构和范围、递归的定义。
2.1.4 共享上下文(Shared Context)
当两个商家开始一个事物,必定有一个相关的一个上下文(Context)。这个上下文能以特殊的协定(例如折扣规则、优惠价格规则)的形式出现或者以仅适用于特定的合作伙伴的商业规则形式出现,这样会造成对不同的合作伙伴的事物处理不同。而且,一个商业合作可能在一个短时间内包括多个调用。每个调用都可能被绑在一个共享的上下文中,它需要横跨在整个合作实例的生命周期中。
在一个J2EE网络服务中,推荐使用离散的位置存放上下文。作为一个开发者,你应该考虑到复杂网络服务需要上下文并计划把它放在你的架构中离散的组件中来处理。现在,上下文处理可以通过手工使用JDBC(Java Database Connectivity)来实现普通数据库编码。然而,将来的上下文API也在计划中,它可能使得网络服务系统的上下文需求流水线化。上下文数据可以被任何组件访问,例如servlet, JSP, 或 EJB 组件。
2.1.5 商业层(Business Layer)
一旦接收的XML数据被解释成了Java对象,数据已经准备好了用于EJB商业层处理。EJB技术是Java中用于创建商业组件的标准。使用EJB组件,你能够从容器获得后端服务,例如安全、事物、永久化、连接池、载荷均衡以及错误修复服务。
EJB 2.0标准中有三种EJB组件:
译者注:下面这些定义已经很古老(相对而言),为了保持完整性请看原文:
Session Beans perform work on behalf of clients (they are verbs). Session beans are generally short-lived and perform fairly quick actions, such as trading a stock, submitting a purchase order, or calculating taxes on a transaction.
Entity Beans represent business data (they are nouns). They are generally long lived and map to an underlying storage, such as an RDBMS or OODBMS system. There are two subtypes of entity beans: bean-managed persistent (where you write the persistence logic) and container-managed persistent (where the container generates the persistence logic for you). Some examples of entity beans include stocks, orders, customers, employees, and accounts.
MessageDriven Beans are message-oriented components. They receive messages using message-oriented middleware, such as IBM MQSeries or TIBCO Rendezvous. Messages can also be sent from Java clients using the Java Message Service (JMS) standard. When a message arrives for a message-driven bean, it is similarly accessed using the JMS API. Examples of message-driven beans include a logging service, a stock trading service, or an order submission service.
通常,session beans调用entity beans来获得需要的动作。例如,一个用来计算定购价格的价格引擎是一个session beans,它被用于一个或多个产品和定购entity beans中。消息驱动beans接收消息且路由消息到session beans或者entity beans。
图6是一个EJB组件交互的例子
图 6 EJB商业层
我们使用Java Naming and Directory Interface (JNDI) API建立、寻找和销毁EJB组件。这个API典型用于访问许多类型的J2EE平台的外部资源,包括数据库引擎、面向消息的中间件引擎或者EJB组件工厂。
EJB的详细信息,可参看:
http://java.sun.com/products/ejb/white/white_paper.html
http://java.sun.com/products/ejb/
"Mastering Enterprise JavaBeans" by Ed Roman, published by John Wiley & Sons.