扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年9月22日
关键字:
在本页阅读全文(共4页)
注意 float 和 double 类型的使用
首先需要注意的一点是,正如您所知,CLDC 1.0 (Connected Limited Device Configuration) 并没有出于性能的原因而提供 float 和 double 本机类型,即使 CLDC 1.1 和 CDC 都为其提供了支持。那么,如果您必须使用针对 CLDC 1.0 的 Web 服务,您该如何做呢?JSR-172 为您提供了部分答案。
为了在 CLDC 1.0 中缺省支持 xsd:float 和 xsd:double,实现必须 生成代码来将这些类型映射到 java.lang.String。为了支持为 float 和 double 提供本机支持的配置和平台(CLDC 1.1 和 CDC),存根生成器实现也必须 生成代码来将这些类型映射到适当的本机 Java 类型。(详细信息,请参阅参考资料,以获得指向 JSR-172: J2ME Web 服务规范的链接。)
我将演示一个添加两个 float 数的简单 Web 服务(清单 7)。
清单 7. 添加两个 float 数
public class TaskWs { public TaskWs() { } /** * Adding two float numbers and return their sum * @param a First number to add, * @param b Second number to add * @return The sum of a and b. */ public float addTwo(float a, float b) { return a + b; } } } |
所生成的 WSDL 定义中的 XML 数据类型定义如清单 8 所示。
清单 8. 与清单 7 对应的 WSDL 定义
<wsdl:types> <schema targetNamespace="http://ws.test.ibm.com" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://ws.test.ibm.com" xmlns:intf="http://ws.test.ibm.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <element name="addTwoResponse"> <complexType> <sequence> <element name="addTwoReturn" type="xsd:float"/> </sequence> </complexType> </element> <element name="addTwo"> <complexType> <sequence> <element name="a" type="xsd:float"/> <element name="b" type="xsd:float"/> <element name="b" type="xsd:float"/> </sequence> </complexType> </element> </schema> </wsdl:types> |
对于针对 CLDC 1.0 的 Web 服务客户端,所生成的存根如清单 9 所示。
清单 9. 为 CLDC 1.0 生成的客户端存根
public interface TaskWs extends java.rmi.Remote { public java.lang.String addTwo(java.lang.String _a, java.lang.String _b) throws java.rmi.RemoteException, javax.xml.rpc.JAXRPCException; } |
所以,当调用 CLDC 1.0 中的 Web 服务时,您必须使用 addTwo() 方法提供两个 String 参数,而对于针对平台 CLDC 1.1 的 Web 服务客户端,所生成的服务接口与清单 10 中所描述的类似:
清单 10. 为 CLDC 1.1 生成的客户端存根
public interface TaskWs extends java.rmi.Remote { public float addTwo(float _a, float _b) throws java.rmi.RemoteException, javax.xml.rpc.JAXRPCException; } |
这将 xsd:float 映射到所生成的客户端存根中的 float 类型。看到 CLDC 1.0 和 CLDC 1.1 之间的不同之处了吗?
在为移动设备开发 Web 服务时,请注意 float 和 double 类型,因为 CLDC 1.0 虚拟机实现无法加载为 CLDC 1.1 生成的存根(使用到 float 和 double 的本机映射)。同时针对 CLDC 1.0 和 CLDC 1.1 的 Java 2 Platform Micro Edition (J2ME) 应用程序的开发人员应该使用到 java.lang.String 的缺省映射,以获得最好可重用性。
在处理输入和输出参数时注意可能出现的问题
JSR-172 指定了以副本的形式传送并以副本的形式创建返回值的所有参数。但是,当处理数据集合时,零数组 (返回零)和空数组 (返回其本身)需要密切关注。
我的建议是尽可能地避免使用空数组。当处理移动 Web 服务时,空数组可能是一个问题。
假定您需要返回任务对象数组。原始代码如清单 11 所示。
清单 11. 一个简单的值对象
public class SimpleTask { /** * The name of the task */ private String name; /** * The default constructor * */ public SimpleTask() { } /** * @return Returns the name of the task. */ public String getName() { return name; } /** * @param name * The name to set. */ public void setName(String name) { this.name = name; } } |
Web 服务实现如清单 12 所示。
清单 12. 返回值对象的数组的方法
1 public SimpleTask[] getSimpleTasks(){ 2 SimpleTask[] tasks = null; 3 /* 4 * Your code dealing with DB goes here 5 * .... 6 * tasks = ... 7 */ 8 return tasks; 9 } |
当生成 Web 服务存根和使用生成的存根测试 Web 服务时,本例中的每一个部分都将正常工作。但是,因为在结束一个阶段之前您需要使用 Jtest 进行完整的代码检查,所以当您对代码片段运行 Jtest 时,您将看到一条建议:“Return zero-length arrays instead of null”。在犹豫片刻之后后,您将赞同 Jtest 的建议。如果您返回零数组,该代码的客户端必须编写额外的代码来检查返回值是否为零(如清单 13 所示)。
清单13. 用于调用 Web 服务的客户端代码片段
SimpleTask[] tasks = service.getSimpleTasks(); if(tasks != null){ int length = tasks.length; //do something here } |
当您将 SimpleTask[] tasks = null;(清单 12 中的第 2 行)修改为 SimpleTask[] tasks = new SimpleTasks[0]; 时,您只需将清单 13 编写为:
SimpleTask[] tasks = service.getSimpleTasks(); int length = tasks.length; |
在修改之后,您会认为代码逻辑没有更改,并再次运行客户端来调用 Web 服务,但是现在却引发了异常。到目前为止,您已经根据 Jtest 的建议做了许多小的修补――您忘记修改了什么――这可能导致需要花额外的时间来努力找到发生错误的原因。这个过程真的漫长而乏味。
那么,问题究竟出在什么地方呢?一般来说,对于零对象数组(如 SimpleTask),返回的 SOAP 消息如清单 14 所示。
清单 14. 返回零数组时的 SOAP 消息
<soapenv:Body> <p147:getSimpleTasksResponse xmlns:p147="http://ws.test.ibm.com"> <getSimpleTasksReturn xsi:nil="true" /> </p147:getSimpleTasksResponse> </soapenv:Body> |
对于空数组(如 SimpleTask[] tasks = new SimpleTask[0]),SOAP 消息如清单 15 所示。
清单 15. 返回空数组时的 SOAP 消息
<soapenv:Body> <p147:getSimpleTasksResponse xmlns:p147="http://ws.test.ibm.com"> <getSimpleTasksReturn /> </p147:getSimpleTasksResponse> </soapenv:Body> |
其不同之处在于 <getSimpleTasksReturn/> 和 <getSimpleTasksReturn xsi:nil = true> 之间。图 2 说明了空数组参数大部分时间是无效的。对于自定义的数据类型(包括另一个自定类型的数组),不要将类变量初始化为空数组――相反,要将其初始化为零数组,尽管所生成的空数组和零数组的 WSDL 定义是相同的。
图 2. 根据 JSR-172 编码零数组参数和空数组参数
结束语
在处理移动 Web 服务时,您需要更加谨慎,因为移动 Web 服务规范只支持部分 API。如果您计划开发移动 Web 服务,则当您处理值类型和集合类型时,我向您介绍了一些窍门。此外,我还提供了以下信息:
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者