SOAP中复杂类型(JavaBean)调用实例实践

SOAP 中复杂类型 (JavaBean) 调用实例实践

使用工具: axis-1_1

Tomcat 5.2.x

IDE: Eclipse 3.1

一、 简单开始:

1 、创建一个 JavaBean 类 Student.java

package com.kevinGQ.service.axis.model;

import java.io.Serializable;

public class Student implements Serializable{

private String _name;

private String _id;

private String _comment;

public Student(){}

public Student(String name, String id, String comment){

_name = name;

_id = id;

_comment = comment;

}

public String getName(){

return _name;

}

public void setName(String name){

_name = name;

}

public String getId(){

return _id;

}

public void setId(String id){

_id = id;

}

public String getComment(){

return _comment;

}

public void setComment(String comment){

_comment = comment;

}

}

2 、写 Service 程序

package com.kevinGQ.service.axis.service;

import com.kevinGQ.service.axis.model.Student;

public class GetStudentService {

public Student getAStudent(String name){

Student a = new Student("a","10001","I'm A");

return a;

}

}

3 、部署 axis 及部署 service

a. 从 axis-1_1.zip 中将 axis-1_1/webapps/axis 文件夹拷贝到 Tomcat 5.0.x/webapps/

b. 打开 webapps/axis/WEB-INF/server-config.wsdd 进行编辑,在

  1<deployment> 标签下插入如下片断 
  2
  3<service name="StudentInfoService" provider="java:RPC">
  4<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"></parameter>
  5<parameter name="allowedMethods" value="*"></parameter>
  6<beanmapping languagespecifictype="java:com.kevinGQ.service.axis.model.Student" qname="myNS:Student" xmlns:myns="urn:StudentInfoService"></beanmapping>
  7</service>
  8
  9片断中  StudentInfoService  是这个  web service  的名字,在客户端编码的时候需要用到。 
 10
 11<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"></parameter>
 12
 13中说明了这个服务提供的类,包括  package  的完整类名。 
 14
 15<parameter name="allowedMethods" value="*"></parameter> 中说明这个服务中可供给外部调用的方法有哪些,  *  表示全部函数,现在也可以把  *  改成  getAStudent. 
 16
 17<beanmapping languagespecifictype="java:com.kevinGQ.service.axis.model.Student" qname="myNS:Student" xmlns:myns="urn:StudentInfoService"></beanmapping> 中说明对于这个  JavaBean  的传输需要如何对它进行  serializing    de-serializing  ,说明的目的在于绑定  JavaBean  的对象类别。注意标签中说明的名字空间。这个标签其实是如下标签的一个简写: 
 18
 19<typemapping deserializer="  ` ` ` org.apache.axis.encoding.ser.BeanDeserializerFactory  ` " encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" languagespecifictype="java: com.kevinGQ.service.axis.model.Student " qname="myNs:Student" serializer="  ` org.apache.axis.encoding.ser.BeanSerializerFactory  ` " xmlns:ns="urn:StudentInfoService"></typemapping>
 20
 21c.  把编译好的  Student.class    GetStudentService.class  (在它们各自的包内)  放到  axis/WEB-INF/classes/. 
 22
 234  、启动  Tomcat,  访问  http://localhost:8080/axis/admin.html  ,查看你部署的服务 
 24
 255  、编写客户端 
 26
 27我是在  Eclipse  里完成代码的编写,编译及运行需要把  axis-1_1/lib/  除了  axis_ant.jar    7    jar  文件导入到  classpath. 
 28
 29package com.kevinGQ.service.axis.client; 
 30
 31import java.net.URL; 
 32
 33import javax.xml.namespace.QName; 
 34
 35import javax.xml.rpc.ParameterMode; 
 36
 37import org.apache.axis.client.Call; 
 38
 39import org.apache.axis.client.Service; 
 40
 41import org.apache.axis.encoding.XMLType; 
 42
 43import org.apache.axis.encoding.ser.BeanDeserializerFactory; 
 44
 45import org.apache.axis.encoding.ser.BeanSerializerFactory; 
 46
 47import com.kevinGQ.service.axis.model.Student; 
 48
 49public class GetAStudentClient { 
 50
 51public static void main(String [] args) throws Exception 
 52
 53{ 
 54
 55Service service = new Service(); 
 56
 57Call call = (Call) service.createCall(); 
 58
 59QName qn = new QName("urn:StudentInfoService","Student"); 
 60
 61**call.registerTypeMapping(Student.class,qn, **
 62
 63** new BeanSerializerFactory(Student.class, qn),  **
 64
 65** new BeanDeserializerFactory(Student.class, qn)  **
 66
 67** );  **
 68
 69try{ 
 70
 71call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService")); 
 72
 73call.setOperationName(new QName("StudentInfoService","getAStudent")); 
 74
 75call.addParameter("arg1",XMLType.XSD_STRING, ParameterMode.IN); 
 76
 77call.setReturnClass(Student.class); 
 78
 79Student a = (Student) call.invoke(  new Object[]{"a"}  ); 
 80
 81System.out.println(a.getId()); 
 82
 83}catch(Exception e) { 
 84
 85System.out.println( "Error : " + e.toString()); 
 86
 87} 
 88
 89} 
 90
 91} 
 92
 93红色代码部分表明任意的一个字符串,因为  getAStudent  方法的参数对返回的结果没有影响,这里只是象征性的传递一个参数。加粗的部分是需要在  Client  端说明要  serialize    de-serialize    JavaBean  类别,参数的说明可参考  axis api  文档。 
 94
 95要得到运行的结果,客户端这边需要得到  Student.class  文件,可是如果对于一个不在本机的服务,如何得到这个  Student.class  呢?——你需要阅读一下这个  WebService    wsdl  文档,里面有对这个  JavaBean  对象中各个域的说明,根据  JavaBean  的编码规范,你自己编写编译就得到了  Student.class  文件。 
 96
 97二、  稍微深入 
 98
 99我想得到的是一个  Student  的数组怎么办呢? 
100
101你只有稍做修改: 
102
1031  、服务端的一个新类  StudentLib.java 
104
105package com.kevinGQ.service.axis.model; 
106
107import java.util.ArrayList; 
108
109public class StudentLib { 
110
111ArrayList studentLib = null; 
112
113public StudentLib(){ 
114
115studentLib = new ArrayList(); 
116
117} 
118
119public void addStudent(Student s){ 
120
121studentLib.add(s); 
122
123} 
124
125public ArrayList getStudents(String name, String id){ 
126
127ArrayList list = new ArrayList(); 
128
129for(int i = 0; i &lt; studentLib.size(); i++){ 
130
131if(this.get(i).getName().equals(name) 
132
133&amp;&amp; this.get(i).getId().equals(id)){ 
134
135list.add(this.get(i)); 
136
137} 
138
139} 
140
141return list; 
142
143} 
144
145public Student get(int index){ 
146
147return (Student)studentLib.get(index); 
148
149} 
150
151} 
152
153这个类只不过是为了实现稍微复杂点的逻辑功能而写。注意  getStudents  方法返回的是  ArrayList  类型的引用。因为  SOAP  中支持的数据类型包含  java    ArrayList  ,所以用这个类型会方便很多。 
154
1552  、扩展  Service  程序 
156
157package com.kevinGQ.service.axis.service; 
158
159import java.util.ArrayList; 
160
161import com.kevinGQ.service.axis.model.Student; 
162
163import com.kevinGQ.service.axis.model.StudentLib; 
164
165public class GetStudentService { 
166
167**public ArrayList getStudent(){ **
168
169** ArrayList students = new ArrayList();  **
170
171** Student a = new Student("a","10001","I'm A");  **
172
173** Student b = new Student("a","10002","I'm B");  **
174
175** Student c = new Student("a","10001","I'm A, I'm not C");  **
176
177** StudentLib lib = new StudentLib();  **
178
179** lib.addStudent(a);  **
180
181** lib.addStudent(b);  **
182
183** lib.addStudent(c);  **
184
185** **
186
187** students = lib.getStudents("a","10001");  **
188
189** return students;  **
190
191** }  **
192
193public Student getAStudent(String name){ 
194
195Student a = new Student("a","10001","I'm A"); 
196
197return a; 
198
199} 
200
201} 
202
203加粗的地方为添加的新的方法,我们接着要在服务端描述它 
204
2053  、部署  service 
206
207把刚才添加到  server-config.wsdd  的那个片断再拿出来看看,好像不用修改(只要你在  allowedMethods  的地方表明允许暴露的方法的是  *   
208
2094  、写个客户端看看 
210
211package com.kevinGQ.service.axis.client; 
212
213import java.net.URL; 
214
215import java.util.ArrayList; 
216
217import org.apache.axis.client.Call; 
218
219import org.apache.axis.client.Service; 
220
221import org.apache.axis.encoding.XMLType; 
222
223import org.apache.axis.encoding.ser.BeanDeserializerFactory; 
224
225import org.apache.axis.encoding.ser.BeanSerializerFactory; 
226
227import com.kevinGQ.service.axis.model.Student; 
228
229import javax.xml.namespace.QName; 
230
231import javax.xml.rpc.ParameterMode; 
232
233public class GetStudentClient { 
234
235public static void main(String [] args) throws Exception 
236
237{ 
238
239Service service = new Service(); 
240
241Call call = (Call) service.createCall(); 
242
243QName qn = new QName("urn:StudentInfoService","Student"); 
244
245call.registerTypeMapping(Student.class,qn, 
246
247new BeanSerializerFactory(Student.class, qn), 
248
249new BeanDeserializerFactory(Student.class, qn)); 
250
251try{ 
252
253call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService")); 
254
255call.setOperationName(new QName("StudentInfoService","getStudent")); 
256
257; 
258
259**call.setReturnClass(ArrayList.class); **
260
261ArrayList result = (ArrayList) call.invoke(new Object[]{}); 
262
263for(int i = 0; i &lt; result.size(); i++){ 
264
265Student stu = (Student)result.get(i); 
266
267System.out.println(stu.getName()+" "+stu.getId()+" "+stu.getComment()); 
268
269} 
270
271}catch(Exception e) { 
272
273System.out.println( "Error : " + e.toString()); 
274
275} 
276
277} 
278
279} 
280
281和第一个客户端很相似吧。注意把  Call  返回的类型设为  ArrayList  ,看代码中加粗部分! 
282
283结果输出了  2  条记录,和预期的一样。要不,你试试。 
284
285附:文中描述服务的  wsdl.xml   
286<?xml version="1.0" encoding="UTF-8"?>
287<wsdl:definitions targetnamespace=" http://localhost:8080/axis/services/StudentInfoService " xmlns:apachesoap=" http://xml.apache.org/xml-soap " xmlns:impl=" http://localhost:8080/axis/services/StudentInfoService " xmlns:intf=" http://localhost:8080/axis/services/StudentInfoService " xmlns:soapenc=" http://schemas.xmlsoap.org/soap/encoding/ " xmlns:tns1="urn:StudentInfoService" xmlns:wsdl=" http://schemas.xmlsoap.org/wsdl/ " xmlns:wsdlsoap=" http://schemas.xmlsoap.org/wsdl/soap/ " xmlns:xsd=" http://www.w3.org/2001/XMLSchema ">
288<wsdl:types>
289<schema targetnamespace="urn:StudentInfoService" xmlns=" http://www.w3.org/2001/XMLSchema ">
290<import namespace=" http://schemas.xmlsoap.org/soap/encoding/">
291<complextype name="Student">
292<sequence>
293<element name="comment" nillable="true" type="xsd:string"></element>
294<element name="name" nillable="true" type="xsd:string"></element>
295<element name="id" nillable="true" type="xsd:string"></element>
296</sequence>
297</complextype>
298</import></schema>
299</wsdl:types>
300<wsdl:message name="getAStudentRequest">
301<wsdl:part name="name" type="xsd:string"></wsdl:part>
302</wsdl:message>
303<wsdl:message name="getAStudentResponse">
304<wsdl:part name="getAStudentReturn" type="tns1:Student"></wsdl:part>
305</wsdl:message>
306<wsdl:message name="getStudentResponse">
307<wsdl:part name="getStudentReturn" type="soapenc:Array"></wsdl:part>
308</wsdl:message>
309<wsdl:message name="getStudentRequest">
310</wsdl:message>
311<wsdl:porttype name="GetStudentService">
312<wsdl:operation name="getStudent">
313<wsdl:input message="impl:getStudentRequest" name="getStudentRequest"></wsdl:input>
314<wsdl:output message="impl:getStudentResponse" name="getStudentResponse"></wsdl:output>
315</wsdl:operation>
316<wsdl:operation name="getAStudent" parameterorder="name">
317<wsdl:input message="impl:getAStudentRequest" name="getAStudentRequest"></wsdl:input>
318<wsdl:output message="impl:getAStudentResponse" name="getAStudentResponse"></wsdl:output>
319</wsdl:operation>
320</wsdl:porttype>
321<wsdl:binding name="StudentInfoServiceSoapBinding" type="impl:GetStudentService">
322<wsdlsoap:binding style="rpc" transport=" http://schemas.xmlsoap.org/soap/http">
323<wsdl:operation name="getStudent">
324<wsdlsoap:operation soapaction=""></wsdlsoap:operation>
325<wsdl:input name="getStudentRequest">
326<wsdlsoap:body encodingstyle=" http://schemas.xmlsoap.org/soap/encoding/ " namespace=" http://service.axis.service.kevinGQ.com " use="encoded"></wsdlsoap:body>
327</wsdl:input>
328<wsdl:output name="getStudentResponse">
329<wsdlsoap:body encodingstyle=" http://schemas.xmlsoap.org/soap/encoding/ " namespace=" http://localhost:8080/axis/services/StudentInfoService " use="encoded"></wsdlsoap:body>   
330&lt;/</wsdl:output></wsdl:operation></wsdlsoap:binding></wsdl:binding></wsdl:definitions></deployment>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus