第五章 web service 中接受多个参数
第五章 web service 中接受多个参数
上一章 理解web service的调用过程(calling process)
本章主要内容:
如何在实现类中接受多个参数
1. 接受多个参数
考虑类SimpleServiceImpl:
2
3 public ConcatResponse concat(ConcatRequest concatRequest0) {
4
5 String result = concatRequest0.getS1() + concatRequest0.getS2();
6
7 ConcatResponse response = new ConcatResponse();
8
9 response.setConcatResponse(result);
10
11 return response;
12
13 }
14
15 }
因为这个web service是文档类型的,在输入消息(Input message)包含一个part。因此在服务实现类中对应一个参数。对于输出消息也是类似的。如果实现类能够如下实现,将会更直接方便:
2
3 public String concat(String s1, String s2) {
4
5 return s1+s2;
6
7 }
8
9 }
10
在消息中,若依然是接受一个part(<concatRequest>)。如果实现多个参数,仅仅需要对WSDL文件作两个地方的修改:

对于output message道理也是类似的,元素名必须是操作名加上后缀”Response”并且元素必须是一个序列(sequence):

接下来,我们进行验证。拷贝工程SimpleService并保存为工程WrappedService.删除所有的Java 文件。”out”文件夹依然链接到原来的位置(c:\axis\repository\services\SimpleService).切换到eclipse导航视图并打开.project 文件:

把.project 文件中的路径改为c:\axis\repository\services\WrappedService:

把文件SimpleService.wsdl重命名为WrappedService.wsdl 并做以下修改:
2
3 <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
4
5 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6
7 xmlns:tns="http://ttdev.com/ss"
8
9 xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WrappedService"
10
11 targetNamespace="http://ttdev.com/ss">
12
13 <wsdl:types>
14
15 <xsd:schema targetNamespace="http://ttdev.com/ss"
16
17 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
18
19 <xsd:element name="concat">
20
21 <xsd:complexType>
22
23 <xsd:sequence>
24
25 <xsd:element name="s1" type="xsd:string" />
26
27 <xsd:element name="s2" type="xsd:string" />
28
29 </xsd:sequence>
30
31 </xsd:complexType>
32
33 </xsd:element>
34
35 <xsd:element name="concatResponse">
36
37 <xsd:complexType>
38
39 <xsd:sequence>
40
41 <xsd:element name="r" type="xsd:string" />
42
43 </xsd:sequence>
44
45 </xsd:complexType>
46
47 </xsd:element>
48
49 </xsd:schema>
50
51 </wsdl:types>
52
53 <wsdl:message name="concatRequest">
54
55 <wsdl:part name="parameters" element="tns:concat" />
56
57 </wsdl:message>
58
59 <wsdl:message name="concatResponse">
60
61 <wsdl:part name="parameters" element="tns:concatResponse" />
62
63 </wsdl:message>
64
65 <wsdl:portType name="WrappedService">
66
67 <wsdl:operation name="concat">
68
69 <wsdl:input message="tns:concatRequest" />
70
71 <wsdl:output message="tns:concatResponse" />
72
73 </wsdl:operation>
74
75 </wsdl:portType>
76
77 <wsdl:binding name="WrappedServiceSOAP" type="tns:WrappedService">
78
79 <soap:binding style="document"
80
81 transport="http://schemas.xmlsoap.org/soap/http" />
82
83 <wsdl:operation name="concat">
84
85 <soap:operation
86
87 soapAction="http://ttdev.com/ss/NewOperation" />
88
89 <wsdl:input>
90
91 <soap:body use="literal" />
92
93 </wsdl:input>
94
95 <wsdl:output>
96
97 <soap:body use="literal" />
98
99 </wsdl:output>
100
101 </wsdl:operation>
102
103 </wsdl:binding>
104
105 <wsdl:service name="WrappedService">
106
107 <wsdl:port binding="tns:WrappedServiceSOAP"
108
109 name="WrappedServiceSOAP">
110
111 <soap:address
112
113 location="http://localhost:8080/axis2/services/WrappedService" />
114
115 </wsdl:port>
116
117 </wsdl:service>
118
119 </wsdl:definitions>
更改build.xml:

接下来一个步骤非常重要:我们需要一个特殊的service stub,怎么个特殊法呢?它可以执行一些特殊的处理操作(如下图所示). 当一个<concat>元素到来时,service stub 将从<concat>元素中获得<s1>和<s2>两个元素,并把这两个参数作为两个参数的值(这个功能成为解封装”unwrapping”).当服务返回一个字符串,service stub将把这个返回值作为<r>元素的值,并且把<r>元素放入到<concatResponse>元素中(这个功能称为封装”wrapping”):

这里需要注意的是,这个service依然是一个文档类型的service。客户端依然用相同的方式对其调用(除了<concatRequest>改为了<concat>). 不同的是service stub调用你的实现并且如何处理返回值。这些不同队客户端来说是透明的。为了生成这样的service stub,需要在Ant任务<wsdl2code>加上选项:

运行build.xml 文件生成service stub和client stub。BUG提示:在Axis2 1.3中有一个bug阻止任务<wsdl2code>覆盖文件services.xml.所以首先把文件services.xml删除然后再运行build.xml。刷新工程。检查WrappedServiceSkeleton.java:
2
3 public String concat(String s11, String s22) {
4
5 ...
6
7 }
8
9 }
10
然后创建一个实现类WrappedServiceImpl:
2
3 public String concat(String s1, String s2) {
4
5 return s1 + s2;
6
7 }
8
9 }
10
11
启动Axis服务器,在客户包中创建一个WrappedClient.java类:

运行程序,运行正常!
2. 互操作性
通过封装简化实现是一个好主意。但目前只有.NET框架支持这类web service。很明显Axis已经实现了这种封装。从调用者角度看,这只是一种document+literal类型的web service。所以如果调用者不理解这种封装协定,依然可以按照通常的文档类型方式进行访问。
3. 本章总结
任务<wsdl2code>支持封装协定(wrapped convention)这样服务实现类可以接收多个参数。如果客户理解这种协定可以通过多个参数进行服务的调用。对于那些不理解这种协定的,依然可以按照常规的文档类型服务进行调用。
为了保证和.net平台的互操作性,需要理解这个封装协定。
浙公网安备 33010602011771号