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进行编辑,在<deployment>标签下插入如下片断
<service name="StudentInfoService" provider="java:RPC">
<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>
<parameter name="allowedMethods" value="*"/>
<beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>
</service>
片断中StudentInfoService是这个web service的名字,在客户端编码的时候需要用到。
<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>
中说明了这个服务提供的类,包括package的完整类名。
<parameter name="allowedMethods" value="*"/>中说明这个服务中可供给外部调用的方法有哪些,*表示全部函数,现在也可以把*改成getAStudent.
<beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>中说明对于这个JavaBean的传输需要如何对它进行serializing和de-serializing,说明的目的在于绑定JavaBean的对象类别。注意标签中说明的名字空间。这个标签其实是如下标签的一个简写:
<typeMapping qname="myNs:Student" xmlns:ns="urn:StudentInfoService"
languageSpecificType="java: com.kevinGQ.service.axis.model.Student "
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory "
deserializer=" org.apache.axis.encoding.ser.BeanDeserializerFactory "
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
c. 把编译好的Student.class 和 GetStudentService.class(在它们各自的包内) 放到axis/WEB-INF/classes/.
4、启动Tomcat, 访问http://localhost:8080/axis/admin.html,查看你部署的服务
5、编写客户端
我是在Eclipse里完成代码的编写,编译及运行需要把axis-1_1/lib/ 除了axis_ant.jar外7个jar文件导入到classpath.
package com.kevinGQ.service.axis.client;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import com.kevinGQ.service.axis.model.Student;
public class GetAStudentClient {
public static void main(String [] args) throws Exception
{
Service service = new Service();
Call call = (Call) service.createCall();
QName qn = new QName("urn:StudentInfoService","Student");
call.registerTypeMapping(Student.class,qn,
new BeanSerializerFactory(Student.class, qn),
new BeanDeserializerFactory(Student.class, qn)
);
try{
call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService"));
call.setOperationName(new QName("StudentInfoService","getAStudent"));
call.addParameter("arg1",XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnClass(Student.class);
Student a = (Student) call.invoke(new Object[]{"a"});
System.out.println(a.getId());
}catch(Exception e) {
System.out.println( "Error : " + e.toString());
}
}
}
红色代码部分表明任意的一个字符串,因为getAStudent方法的参数对返回的结果没有影响,这里只是象征性的传递一个参数。加粗的部分是需要在Client端说明要serialize和de-serialize的JavaBean类别,参数的说明可参考axis api 文档。
要得到运行的结果,客户端这边需要得到Student.class文件,可是如果对于一个不在本机的服务,如何得到这个Student.class呢?——你需要阅读一下这个WebService的wsdl文档,里面有对这个JavaBean对象中各个域的说明,根据JavaBean的编码规范,你自己编写编译就得到了Student.class文件。
二、稍微深入
我想得到的是一个Student的数组怎么办呢?
你只有稍做修改:
1、服务端的一个新类 StudentLib.java
package com.kevinGQ.service.axis.model;
import java.util.ArrayList;
public class StudentLib {
ArrayList studentLib = null;
public StudentLib(){
studentLib = new ArrayList();
}
public void addStudent(Student s){
studentLib.add(s);
}
public ArrayList getStudents(String name, String id){
ArrayList list = new ArrayList();
for(int i = 0; i < studentLib.size(); i++){
if(this.get(i).getName().equals(name)
&& this.get(i).getId().equals(id)){
list.add(this.get(i));
}
}
return list;
}
public Student get(int index){
return (Student)studentLib.get(index);
}
}
这个类只不过是为了实现稍微复杂点的逻辑功能而写。注意getStudents方法返回的是ArrayList类型的引用。因为SOAP中支持的数据类型包含java中ArrayList,所以用这个类型会方便很多。
2、扩展Service程序
package com.kevinGQ.service.axis.service;
import java.util.ArrayList;
import com.kevinGQ.service.axis.model.Student;
import com.kevinGQ.service.axis.model.StudentLib;
public class GetStudentService {
public ArrayList getStudent(){
ArrayList students = new ArrayList();
Student a = new Student("a","10001","I'm A");
Student b = new Student("a","10002","I'm B");
Student c = new Student("a","10001","I'm A, I'm not C");
StudentLib lib = new StudentLib();
lib.addStudent(a);
lib.addStudent(b);
lib.addStudent(c);
students = lib.getStudents("a","10001");
return students;
}
public Student getAStudent(String name){
Student a = new Student("a","10001","I'm A");
return a;
}
}
加粗的地方为添加的新的方法,我们接着要在服务端描述它
3、部署service
把刚才添加到server-config.wsdd的那个片断再拿出来看看,好像不用修改(只要你在allowedMethods的地方表明允许暴露的方法的是*)
4、写个客户端看看
package com.kevinGQ.service.axis.client;
import java.net.URL;
import java.util.ArrayList;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import com.kevinGQ.service.axis.model.Student;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
public class GetStudentClient {
public static void main(String [] args) throws Exception
{
Service service = new Service();
Call call = (Call) service.createCall();
QName qn = new QName("urn:StudentInfoService","Student");
call.registerTypeMapping(Student.class,qn,
new BeanSerializerFactory(Student.class, qn),
new BeanDeserializerFactory(Student.class, qn));
try{
call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService"));
call.setOperationName(new QName("StudentInfoService","getStudent"));
;
call.setReturnClass(ArrayList.class);
ArrayList result = (ArrayList) call.invoke(new Object[]{});
for(int i = 0; i < result.size(); i++){
Student stu = (Student)result.get(i);
System.out.println(stu.getName()+" "+stu.getId()+" "+stu.getComment());
}
}catch(Exception e) {
System.out.println( "Error : " + e.toString());
}
}
}
和第一个客户端很相似吧。注意把Call返回的类型设为ArrayList,看代码中加粗部分!
结果输出了2条记录,和预期的一样。要不,你试试。
附:文中描述服务的wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<wsdl:types>
<schema targetNamespace="urn:StudentInfoService" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="Student">
<sequence>
<element name="comment" nillable="true" type="xsd:string"/>
<element name="name" nillable="true" type="xsd:string"/>
<element name="id" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getAStudentRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="getAStudentResponse">
<wsdl:part name="getAStudentReturn" type="tns1:Student"/>
</wsdl:message>
<wsdl:message name="getStudentResponse">
<wsdl:part name="getStudentReturn" type="soapenc:Array"/>
</wsdl:message>
<wsdl:message name="getStudentRequest">
</wsdl:message>
<wsdl:portType name="GetStudentService">
<wsdl:operation name="getStudent">
<wsdl:input message="impl:getStudentRequest" name="getStudentRequest"/>
<wsdl:output message="impl:getStudentResponse" name="getStudentResponse"/>
</wsdl:operation>
<wsdl:operation name="getAStudent" parameterOrder="name">
<wsdl:input message="impl:getAStudentRequest" name="getAStudentRequest"/>
<wsdl:output message="impl:getAStudentResponse" name="getAStudentResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="StudentInfoServiceSoapBinding" type="impl:GetStudentService">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getStudent">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getStudentRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://service.axis.service.kevinGQ.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getStudentResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/StudentInfoService" use="encoded"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAStudent">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAStudentRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://service.axis.service.kevinGQ.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getAStudentResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/StudentInfoService" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="GetStudentServiceService">
<wsdl:port binding="impl:StudentInfoServiceSoapBinding" name="StudentInfoService">
<wsdlsoap:address location="http://localhost:8080/axis/services/StudentInfoService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
本文地址:http://com.8s8s.com/it/it41839.htm