六、传递、返回复杂类型的对象

简介:

上面的服务传递的是简单数据类型,返回的也是简单数据类型。下面我们用JavaBean 、List、Map、Array等返回值或参数完成WebService。

1、首先看看JavaBean模式的参数和返回值的WebService,JavaBean代码如下:

 

代码

 

 

没有上面特别就是一个普通的Java对象,里面提供一些属性及getter、setter方法和toString方法(在显示数据的时候有用),值得注意的是在远程调用的Java对象都需要实现Serializable接口,这样在网络中传递对象的时候就不会出现重复的JavaBean。用过或是了解EJB、RMI的朋友应该知道这点。序列化后的对象可以用io进行序列化写入到文件中,也可以反序列化解析到对象中的数据。

 

2、好,回正题。下面编写WebService的服务器端代码。

 

代码

 

3、编写wsdd文本发布当前WebService,wsdd文件代码如下:

 

代码

 

 

 

和上面的wsdd文件不同的是,这里多了beanMapping的配置。Qname是xml中规范限定名称,由命名空间url、本地名称、前缀组成,本地名称是必需的且qname是不可变的。后面的myNSD(namespace)是必需的,是通过前面的qname指定的,myNSD后面的urn:User就和程序中的QName对应的第一个参数,第二个参数对应配置文件中的qname的myNSD冒号后面的值。languageSpecificType是javaBean的类路径。

 

4、发布WebService,还是允许命令行:

java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/AxisWebService/services/AdminService deployComplex.wsdd

发布后,在浏览器中请求:

http://localhost:8080/AxisWebService/servlet/AxisServlet

就可以看到发布的WebService和暴露的方法了。

 

5、客户端代码的编写,这次客户端和以前有些不一样。因为这里设置了参数和返回值都是复杂类型,而不是简单的类型了。代码如下:

 

代码

 

 

需要说明的是,这里传递的User和服务器端的User是同一个对象,在实际开发中应该不是同一个对象的。如java调用.net的WebService,传递的对象应该不是同一个。需要我们自己根据wsdl文件中的描述创建JavaBean。注意的是对象一个要序列化。

new QName("urn:User", "User")这里的QName的urn:User和wsdd文件中的对应,参数User也是和wsdd文件中的qname="myNSD:User"对应的

这里是将对象序列化和反序列化的配置

call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));

User是Mapping的对象,也就是更加wsdl中参数描述创建的Java对象

call.addParameter("i", XMLType.XSD_INT, ParameterMode.IN);设置参数信息,ParameterMode.IN代表传递的参数,XMLType.XSD_INT,代表参数的类型,前面的i是参数名称

call.setReturnClass(User[].class);设置返回值的类型

特别说明:

A、 如果你调用的方法有返回值,一定要设置返回值的类型。call.setReturnClass

B、 如果你调用的方法有参数,一定要设置参数的类型call.addParameter

C、 记得添加wsdl4j.jar,序列化转换的时候需要用到,否则会出现找不到类型异常

 

运行后,效果如下:

客户端:

============getUser=============

41#jackson#jackson@hoo.com#china

============setUser=============

- No returnType was specified to the Call object!  You must call setReturnType() if you have called addParameter().

============getUsers List=============

41#jack#0#jack0@hoo.com#china

41#jack#1#jack1@hoo.com#china

41#jack#2#jack2@hoo.com#china

41#jack#3#jack3@hoo.com#china

============setUsers List=============

- No returnType was specified to the Call object!  You must call setReturnType() if you have called addParameter().

============getUserMap=============

{A=41#jack##jack@hoo.com#china, B=41#tom#tom@hoo.com#china}

============setUserMap=============

- No returnType was specified to the Call object!  You must call setReturnType() if you have called addParameter().

============getUserArray=============

============setUserArray=============

- No returnType was specified to the Call object!  You must call setReturnType() if you have called addParameter().

 

服务器端:

37#tom#tom@hoo.com#china

37#jack#0#jack0@hoo.com#china

37#jack#1#jack1@hoo.com#china

37#jack#2#jack2@hoo.com#china

37#jack#3#jack3@hoo.com#china

{A=37#jack##jack@hoo.com#china, B=37#tom#tom@hoo.com#china}

37#jack#0#jack0@hoo.com#china

37#jack#1#jack1@hoo.com#china

37#jack#2#jack2@hoo.com#china

 

Map、Array、List、JavaBean都可以顺利转换,不管是参数还是返回值。怎么样,很简单吧!

 

传递内部类 

如果你传递的JavaBean带有内部类,那么你的内部类需要是静态化的,且一样要序列化。为Account对象添加一个属性Birthday,Birthday是一个内部类,

 

代码

 

 

同样我们需要在客户端调用的时候,注册类型序列化和反序列化。

QName qn = new QName("urn:Account", "entity.Account");

call.registerTypeMapping(Account.class, qn, new BeanSerializerFactory(Account.class, qn), new BeanDeserializerFactory(Account.class, qn));

QName qn2 = new QName("urn:Birthday", "Account.Birthday");

call.registerTypeMapping(Birthday.class, qn2, new BeanSerializerFactory(Birthday.class, qn2), new BeanDeserializerFactory(Birthday.class, qn2));

而在wsdd文件中和刚才几乎一样

<beanMapping qname="myNSD:entity.Account" xmlns:myNSD="urn:Account" languageSpecificType="java:com.hoo.entity.Account"/>

<beanMapping qname="myNSD:Account.Birthday" xmlns:myNSD="urn:Birthday" languageSpecificType="java:com.hoo.entity.Account$Birthday"/>com.hoo. com.hoo.entity.Account$Birthday是内部类的表示方式






本文转自hoojo博客园博客,原文链接:http://www.cnblogs.com/hoojo/archive/2010/12/23/1911380.html,如需转载请自行联系原作者
目录
相关文章
|
7月前
通过反射获取方法返回的类型
通过反射获取方法返回的类型
|
7月前
自定义封装一个方法让这个方法可以判断所有的数据类型并返回
自定义封装一个方法让这个方法可以判断所有的数据类型并返回
40 0
|
Java 编译器
重载的方法能否根据返回类型进行区分?
重载的方法不能根据返回类型进行区分。方法的重载是基于方法名称和参数列表来进行区分的,与返回类型无关。这是因为在Java中,编译器在确定要调用哪个重载方法时,仅根据传递给方法的参数来进行决策。
375 0
属性传递
属性传递
71 0
|
编译器
详解函数的三种传递方式
详解函数的三种传递方式
198 0
|
测试技术 Android开发
怎么知道方法的参数有哪些类型呢?
怎么知道方法的参数有哪些类型呢?
214 0
|
C++
C++ 用引用的方式向函数传递数组
C++ 用引用的方式向函数传递数组
149 0
C++ 用引用的方式向函数传递数组
|
API
@JsonView 处理返回值,实现接口返回想要的字段
@JsonView 处理返回的json ,实现返回需要的字段
1665 0
|
C++
浅析C++的引用与const指针与各种传递方式
转自:https://www.jb51.net/article/120561.htm   首先我们知道 const int *p 与 int const *p 是一样的,即 *p 是常量; 而 int * const p 跟上面是不一样的,即 p 是常量; 我们知道引用只是一个别名,与变量共享存储空间,并且必须在定义的时候初始化,而且不能再成为别的变量的别名,这让我们想到什么呢,貌似跟  int * const p   的性质很像。
1212 0