级别: 初级
C. Enrique Ortiz (eortiz@j2medeveloper.com), 移动技术专家和作家, IBM
2004 年 9 月 01 日
用于 Java 2 平台袖珍版 (Java 2 Platform, Micro Edition,J2ME) 的 Web 服务 API (WSA) 是由Java Community Process为 Java 规范请求 172 (JSR 172) 而定义的,这些 API 是两个相互独立的可选包,用于远程服务调用和 XML 解析。他们是针对基于连接设备配置 (Connected Device Configuration,CDC) 和有限连接设备配置 (Connected Limited Device Configuration,CLDC 1.0 和 CLDC 1.1) 的框架的。为什么用户应该关注这些呢?因为 JSR 172 在设备层为远程服务调用和 XML 解析提供了支持,也就意味着开发人员不用将这项功能嵌入到每一个应用程序中。本文介绍了远程服务调用可选包 API。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
J2ME 中的 Web 服务
Java 2 平台袖珍版 (J2ME) 平台中的 Web 服务是由 Java 规范请求 172 (JSR 172) 定义的,它与标准 Web 服务遵循同样的规范、结构以及调用模型。我们来回顾一下清单。
与标准 Web 服务的比较
JSR 172 Web 服务 API (WSA) 遵循下面这些核心 Web 服务规范:
注意 JSR 172 不支持统一描述、发现和集成 (UDDI) 2.0规范,该规范定义了如何发现远程服务。
由于有相当多的与 Web 服务相关并且涵盖了不同技术的规范出台,而且越来越多,Web 服务互操作组织 (WS-I)定义了 WS-I 基本概要 1.0 (WS-I Basic Profile,Version 1.0) 来定义 Web 服务规范的最小集,和一致性规则一样,所有的基础 Web 服务提供者和消费者都必须遵守该概要。JSR 172 规范也遵守 WS-I 基本概要。
与标准 Web 服务具有相同的体系结构:
JSR 172 WSA 从客户端访问 Web 服务,从服务-消费者的角度来看,WSA 提供远程服务调用 API (JAX-RPC) 以及运行时环境,从而允许 J2ME 应用程序在 Web 上消费服务,而不是作为服务生产者(端点)来运行。除了这一点差别之外,JSR 172 WSA 体系结构的其它部分与 Web 服务的标准体系结构/组织一致,如下图所示:
图 1 - WSA 高级体系结构该高级体系结构组织如下:
- 客户端,Web 服务消费者:它是 J2ME 应用程序,例如 MIDP 或个人版基于框架的应用程序,JSR 172 存根和支持类,以及 JSR 172 运行时。
- 网络:指的是无线和有线网络以及通信协议,无线和有线网络是 Internet 的一部分。注意 JSR 172 本身没有规定在设备上使用 XML 编码方法,而允许执行程序(只要它们对消费者和生产者是透明的)使用更有效的编码方法,例如在设备和无线网关之间使用二进制协议。
- 服务器,Web 服务生产者:它是一个 Web 服务器,通常位于防火墙和/或代理网关的后面。该服务器可以访问后台资源。
调用模型和数据流与标准 Web 服务相同:
J2ME 应用程序通过 JSR 172 存根和运行时调用远程服务,通常要通过 HTTP 和 SOAP 来进行传输。存根和运行时将与远程服务调用相关的复杂部分都隐藏起来了,包括输入值和返回值如何编码并解码,以及与服务器进行网络通信的管理。方法调用遵循同步请求-应答模型,如下图所示:
图 2 - JSR 172 调用模型*由于调用是按模块进行的,所以您应该把这些调用分派到不同的执行线程中。
消费 Web 服务
要消费 Web 服务,您必须首先创建服务调用存根。让这些存根来执行任务,例如对输入值和返回值进行编码和解码、与 JSR 172 运行时交互来调用远程服务端点。存根通过运行时的服务提供者接口 (SPI) 与运行时进行交互,这样通过概述运行时执行的详细情况,使存根在不同厂商之间的执行更便捷。
存根通常是用工具生成的,该工具读取一个 WSDL XML 文档,文档描述了将要使用到的 Web 服务。同样的,WSDL 文档通常也是通过工具生成的,该工具读取接口定义,例如 Java 接口产生了 WSDL 文档。
从我们移动开发的角度来看,需要消费的 WSDL 文档通常已经存在,您需要做的仅仅是生成 JSR 172 WSA 存根。要生成这些存根,您应该使用例如J2ME Wireless Toolkit 2.1存根生成器这样的工具,如下图所示:
图 3 - 生成 JSR 172 WSA 存根该生成器生成存根 Java 文件,以及相关的支持类。如下一部分所描述的,它还考虑到了 WSDL 到 Java 的数据类型映射。
一旦生成了 JSR 172 JAX-RPC 存根和支持文件,您的应用程序就已经被编译并部署到启用了 JSR 172 的设备上了,消费 Web 服务是很简单的而且几乎是透明的。您很快就会看到,调用远程方法几乎和调用本地方法一样简单。
JSR 172 JAX-RPC 子集 API
JSR 172 远程方法调用 API 是以基于 XML 的 RPC 的 J2SE Java API (JAX-RPC 1.1) 的子集为基础的。它同样遵守 WS-I 基本概要。下面来详细研究一下 JSR 172 JAX-RPC 子集 API:
它支持:
- SOAP 1.1。
- 任何可以传送 SOAP 消息的传输,例如 HTTP 1.1,都有一个定义好的用于 SOAP 1.1 的协议绑定。
- SOAP 消息的文字表示代表一个 RPC 调用或应答。
下面(是)数据类型和相应的 Java 映射:
-
xsd:boolean
到 boolean
或 Boolean
。
-
xsd:byte
到 byte
或 Byte
。
-
xsd:short
到 short
或 Short
。
-
xsd:int
到 int
或 Integer
。
-
xsd:long
到 long
或 Long
。
-
xsd:float
到 float
,或 Float
。对基于 CLDC 1.0 的平台,该数据类型映射到 String。
-
xsd:double
到 double
,或 Double
。对基于 CLDC 1.0 的平台,该数据类型映射到 String。
-
xsd:string
到 String
。
-
xsd:base64Binary
到 byte[]
。
-
xsd:hexBinary
到 byte[]
。
-
xsd:complexType
到基本类型和类类型序列。
-
xsd:QName
到 javax.xml.namespace.QName
。
- 以 XML 数组模式为基础的基本类型和复杂类型(结构中包含基本类型或复杂类型)数组。
它不支持:
- 带附件的 SOAP 消息。
- SOAP 消息处理器。
- SOAP 消息的编码表示。
- 服务端点(不是 Web 服务生产者)。
- 服务发现支持 (UDDI)。
设备端没有规定 XML 编码方法。这样做是通过允许执行程序使用更有效的数据编码方法来帮助减少网络传输,例如在设备和无线网关间使用二进制协议(只要这样编码对消费者和生产者是透明的)。
JSR 172 远程调用 API 包括下面这些包:
-
javax.microedition.xml.rpc
-
javax.xml.namespace
-
javax.xml.rpc
-
java.rmi
(包括确保 JAX-RPC 相关型)
注意这些 API(有一些异常 API,例如 RemoteException)不是直接由应用程序调用,相反,应用程序调用生成的存根。上面的 API 主要是供存根使用的。有关详细信息请参阅 JSR 172 规范和/或 Java 文档。
使用 JSR 172 JAX-RPC 调用远程服务
一旦生成、编译并部署了 JSR 172 JAX-RPC 存根和支持文件,消费远程服务就很容易了。事实上,除了导入 RemoteException,完成最少量的 JAX-RPC 细节初始化工作,您的应用程序不光是看上去,而且运行起来也和非 Web 服务消费者应用程序一样。由于有 JSR 172 存根和运行时,实现这种简单的应用程序是可能的,正如前面提到的,JSR 172 存根和运行时把与远程调用相关的大部分细节都隐藏了。
要调用远程服务,您首先需要实例化存根,完成最少的存根初始化工作,然后就是如何编写调用存根方法。下面的代码片断显示了如何使用 JSR 172 JAX-RPC 调用远程服务。
清单 1:调用远程服务
package j2medeveloper.wsasample
// MIDP
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
...
Form form = new Form("Employee Info");
...
// JAX-RPC
import java.rmi.RemoteException;
String serviceURL = "www.j2medeveloper.com/webservicesample";
...
/**
* Entry point to MIDlet, from start or restart states.
* @throws javax.microedition.midlet.MIDletStateChangeException
*/
public void startApp() throws MIDletStateChangeException {
// Instantiate the service stub.
EmployeeService_Stub service = new EmployeeService_Stub();
// Initialize the stub/service.
service._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
serviceURL);
service._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, new
Boolean(true));
...
display.setCurrent(mainScreen);
}
/**
* Paused state. Release resources (connection, threads, etc).
*/
public void pauseApp() {
...
}
/**
* Destroy state. Release resources (connection, threads, etc).
* @param uc If true when this method is called, the MIDlet must
* cleanup and release all resources. If false the MIDlet may
* throw MIDletStateChangeException to indicate it does not want
* to be destroyed at this time.
* @throws javax.microedition.midlet.MIDletStateChangeException
* to indicate it does not want to be destroyed at this time.
*/
public void destroyApp(boolean uc) throws MIDletStateChangeException {
...
}
:
:
/**
* Command Listener.
* @param c is the LCDUI Command.
* @param d is the source Displayable.
*/
public void commandAction(Command c, Displayable d) {
if (c == UiConstants.COMMAND_GET_EMPINFO) {
Thread th = new Thread(new GetEmpInfoTask());
th.start();
} else {
...
}
:
:
}
/**
* On its own thread, invoke the remote service getEmployeeInfo
*/
public class GetEmpInfoTask implements Runnable {
public void run() {
try {
// Invoke the remote service.
EmployeeInfo empInfo =
service.getEmployeeInfo(empId);
:
:
// Display the employee Information
form.append("Name:" +
empInfo.firstname+empInfo.lastname);
form.append("Status:"+empInfo.status);
:
:
display.setCurrent(form);
} catch (RemoteException e) {
// Handle RMI exception.
} catch (Exception e) {
// Handle exception.
}
}
}
:
:
|
注意远程调用是如何在自己的执行线程中执行的。由于 JSR 172 中的远程调用是按模块进行的,而且如果在主事件线程中调用,用户界面会冻结,直到远程调用结束。
您已经学习了 JSR 172 JAX-RPC 存根是如何生成的。以后,有关详细信息请参考适当的存根生成器文档。
结束语
本文介绍了用于 J2ME 平台的 JSR 172 WSA,重点介绍了用于 J2ME 远程服务调用 API 的 JAX-RPC。另外,还涵盖了 JSR 172 WSA 中用到的核心 Web 服务标准、典型结构以及调用模型。并用一个简短的代码实例回顾了如何消费 Web 服务,即 JAX-RPC 子集 API。
在本文的第 2 部分,我将讨论 JSR 172 XML 解析 API。
参考资料
关于作者
|
|
|
C. Enrique Ortiz 是一位软件工程师,有 14 年多的工作经验,他最近担任 Aligo 公司的移动应用程序主管、AGEA 公司无线副总裁,还是 IBM Pervasive 软件,智能推理系统的一位软件工程师。Enrique 与人合作设计了 Sun Microsystems 的移动 Java 开发人员认证考试。他还与人合著了一本最早的关于 J2ME 的书——用于 J2ME 的移动信息设备框架。Enrique 积极参与无线 Java 社区及各种 J2ME 专家组。您可以通过C. Enrique Ortiz与他联系。
|
分享到:
相关推荐
为了在这些设备上实现Web服务功能,Java Community Process (JCP) 定义了Java规范请求 172 (JSR 172),即Web服务API(WSA),它为J2ME提供了一套API,用于远程服务调用和XML解析。 **一、Web服务API的基础** JSR ...
API 的两个可选软件包对两个功能区域进行标准化,这两个功能区域对于 Web 服务的客户机来说是至关重要的:远程服务调用和 XML 解析。 本文将介绍这两个软件包,展示如何使用它们并描述在 J2ME 无线工具包(J2ME ...
在 J2ME 中,实现 Web 服务功能可以让移动设备与服务器进行数据交互,实现远程调用服务。 1. **J2ME 概述** J2ME 由多个配置和 profiles 组成,如基础配置(Connected Limited Device Configuration, CLDC)和 ...
配置定义了设备的基本硬件和软件特性,而剖面则是在特定配置基础上的一组API集合,用于支持更高级别的功能和服务。 ##### 2. Web Services Web Services是一种遵循标准协议(如HTTP、XML、SOAP等)的应用程序接口...
为了使J2ME设备能够访问Web服务,Sun Microsystems推出了WSA(J2ME Web Services API),这是一个专为J2ME设计的Web服务API,使得移动设备可以通过简单的接口访问远程Web服务。 ##### 2.3 WSA的特点 - **轻量化**:...
这意味着开发者可以利用J2ME开发出能够与Web服务交互的应用程序,从而实现数据交换和远程服务调用等功能。 - **网络通信**:通过HttpConnection类可以实现HTTP协议下的网络请求。 - **Web服务交互**:使用JSR 172...
虽然J2ME主要用于移动设备,但有时需要与服务器端的J2EE应用进行数据交换,例如,通过HTTP协议进行远程方法调用(RMI)或者使用Java Message Service(JMS)进行消息传递。这部分源码可能会展示如何在J2ME应用中集成...
在无线设备上使用Web服务,开发者可以利用远程服务器的计算资源,比如获取天气预报、股票信息或者进行在线支付。MIDP中的JSR 172(Java API for XML Processing,JAXP)和JSR 173(Streaming API for XML,StAX)...
这些技术使得开发者能够构建复杂的B/S架构应用,同时提供对事务管理、持久化、远程方法调用等高级功能的支持。 #### J2ME:Java 2 Micro Edition J2ME是Java 2平台的微型版,旨在为资源受限的设备提供Java运行环境...
JSR-172则定义了Web服务客户端API,让嵌入式设备能够利用Web服务进行数据交换和远程调用。 **总结** J2MEAPI速查手册是一个实用的工具,涵盖了J2ME平台的关键组件和技术,包括MIDP、CLDC、LWUIT、蓝牙通信、数据...
- RMI Profile:提供远程方法调用支持。 - PDA Profile:专门为个人数字助理(PDA)设计。 #### 二、J2ME在无线设备上的应用实践 ##### 2.1 J2ME的CLDC/MIDP软件体系架构 - **CLDC/MIDP软件架构概述:** CLDC/...
通过调用Web服务,这些应用能够利用远程服务器的强大功能,而不需要在本地设备上存储大量数据或执行复杂的计算。 总的来说,kSOAP2-j2ME是J2ME开发中与Web服务交互的重要工具。理解和掌握kSOAP2的使用方法和原理,...
- **概述**:客户端可以通过调用远程 Web Service 接口的方法来访问服务。 - **关键概念**: - **代理类**:客户端调用的本地对象,由工具自动生成。 - **SOAP 消息处理**:客户端可以使用 SOAP Message Handler ...
3. **HTTP支持**:框架内置了对HTTP协议的支持,允许应用程序与远程服务器进行通信,实现数据的获取和发送,支持RESTful API的调用。 4. **模板引擎**:J2MEWF提供了一种简单的模板语言,用于动态生成用户界面,...
ksoap2-android-3.6.2是Android开发者实现SOAP通信的重要工具,提供了简洁的API来调用Web服务。使用这个库,开发者可以专注于业务逻辑,而不用过于关注底层的SOAP协议细节。在实际项目中,正确配置和使用ksoap2-...
- RMI(Remote Method Invocation)用于远程方法调用。 - JAXP(Java API for XML Processing)用于XML处理。 - JMS(Java Message Service)用于消息传递。 - JTA(Java Transaction API)和JTS(Java Transaction ...
J2EE定义了一系列标准和接口,包括但不限于RMI(远程方法调用)、IIOP(Internet Inter-ORB Protocol)、JMS(Java消息服务)、JTA(Java事务API)、JNDI(Java命名和目录接口)等,这些API支持分布式通信、事务...
2. **RMI (Remote Method Invocation)**:这是Java平台上的远程调用API,允许对象方法在不同的JVM上被调用。RMI结合了面向对象技术的优势与远程过程调用的简单性。 3. **自定义隧道类 (Custom tunneling class)**:...
4. **RMI**:Remote Method Invocation,远程方法调用,允许Java对象在不同 JVM(Java虚拟机)之间进行方法调用。 5. **JSP**:Java Server Pages,Java服务器端页面,用于动态生成HTML或其他Web内容的服务器端技术...
4. **Java API for XML-based RPC (JAX-RPC)**: 使用XML格式进行远程过程调用。 5. **SOAP with Attachments API for Java (SAAJ)**: 支持SOAP协议的API,用于实现Web服务。 6. **Servlets**: 一种服务器端技术,...