深入剖析Axis2中返回值为复杂自定义类型值【步步逼近实践篇】
2012-12-24 08:31
441 查看
问:Axis2中到底能否传递复杂以及自定义对象?
答:肯定可以
那如何传递呢?在开发过程中,基本类型已经不能满足要求。所以才有有相应的List,Map,以及User对象,Dog对象等等。
比如传递User对象,我们想象一下,到底我们该怎么样,把这个对象传递过去呢?我们再根据前面讲的Webservice传递协议,该如何办呢?实际上发给服务器中是怎么样的格式呢?
在做Webservice时,肯定很好奇,到底这个东东是如何传递过去的?就宛如,我们学计算机时,计算机处理的信息全部都是二进制,当我们问那图片,视频,怎么运作的在计算机?老师统统告是二进制。虽然我们知道二进制是0011这种形式,但是不是仍然有种想钻到计算机中,探个究竟,想真实的体会,或亲眼见识一下?
所以呢,把抽象的东西具体化,在真实的环境中再现,这样才能深入理解其中的原理。
那我们前面也说过,我们传入一个参数为int的方法,其实就是一段soap消息。那一个我们自定义对象,是如何传递呢?User对象在生成的wsdl中,其实是这样的一段代码:
再复杂的对象,实际上也是有基本类型组成。那我们看一下再调用时,传递的soap消息是如何的?
那接下来进入我们的正题,对于复杂类型参数传递。
我们实际上使用axiom方式调用服务。这种方式,同时也是Axis2的不同于Axis的一个新特性。
首先我们拿一个例子做测试,深入剖析返回内部的传递。
第一:测试返回值为自定义对象User对象。
服务器端,还是按照上传的文档开发。方法如下:
那客户端调用方式如下:
[align=left] 那给大家看一下,客户端调用服务器端的getUser方法,返回来的是个OMElement对象。在上篇博客中的RPC调用方式中,直接返回的是无法转化User对象,提示OmElement对象无法转化成User对象。[/align]
[align=left] 好,我们看一下,服务器给客户端返回的是什么?注意这句代码的输出:[/align]
[align=left] 返回值是个soap消息,soap消息怎么会这样呢?为何不是那样的呢?他是根据什么来呢?为何是"http://test.com",又为何是ax21?大家对输出的信息是否也感到好奇呢?的确,我开始也是很好奇,那请跟着我的思路走,慢慢寻找答案。[/align]
[align=left] 咦,突然发现http://test.com跟代码中的fac.createOMNamespace("http://test.com" , "" );有关联,哦,原来是命名空间呢。说道命名空间,不知道大家是否有点明白?嘻嘻,命名空间是从哪里来?是从wsdl来啊?对,返回的soap消息格式是根据服务端的wsdl信息生成的。那我们在仔细研究一下我们服务端生成的wsdl。[/align]
[align=left] wsdl截取了重要的一部分,跟大家解释一下其中的关键处。[/align]
[align=left] 通过wsdl,我们就稍微明白服务器返回值信息。[/align]
[align=left]
[/align]
[align=left] 那下一步就是如何从返回值soap信息中抽取想要的User对象?[/align]
[align=left] 其实我们就想要返回值信息中age,id信息。那我们脑子中第一个想法是什么呢?我们该如何取到呢?[/align]
[align=left] 好,也许我们第一反应是,解析xml。类似java中的dom方式,解析xml。然后把相应的值,再拼接成User对象。[/align]
[align=left] 恭喜你。答对了,思路确实如此的。[/align]
[align=left] 但是,Axiom方式,不用我们一个个解析,然后自己去拼接。在Axiom中,自动会跟我们拼接成相应的对象,只要你告诉Axiom从哪到哪拼接完毕即可。[/align]
[align=left] 继续观察服务器给我们返回的信息,看一下,我们想从那拼接成User对象?[/align]
[align=left] 实际上,我们是想把<ax21:age>0</ax21:age><ax21:id>100</ax21:id><ax21:name>123ee</ax21:name>放到一个User对象中,可是Axiom是需要把一个整体标签中的东西封装,是寻找一个大标签,然后把其中的信息打包成用户想要的对象。而不是一个个查找。[/align]
[align=left] 这样的话,应该是这个User信息的外边一层标签。就是<ns:return></ns:return>[/align]
[align=left]
[/align]
[align=left] 若是明白这个道理的话,那么我们Axiom方式调用就理解了。[/align]
User u = (User) BeanUtil.processObject(omElement,
User. class, null, true, new DefaultObjectSupplier());
[align=left] [/align]
[align=left] OK,讲到这,不知是否明白其中的原理了?若是懂这个例子的话,那么返回值是List<User>也是很简单了,直接用List.add(u)即可。然后返回值为list就有了。[/align]
[align=left] 这节课讲的是返回值为List对象,这样的话,服务器端不用改动。客户端调用方式不使用RPC方式,而是使用Axiom,当然这种肯定也支持RPC支持的基本类型。那下节课给大家深入讲解传递参数为复杂定义类型。[/align]
答:肯定可以
那如何传递呢?在开发过程中,基本类型已经不能满足要求。所以才有有相应的List,Map,以及User对象,Dog对象等等。
比如传递User对象,我们想象一下,到底我们该怎么样,把这个对象传递过去呢?我们再根据前面讲的Webservice传递协议,该如何办呢?实际上发给服务器中是怎么样的格式呢?
在做Webservice时,肯定很好奇,到底这个东东是如何传递过去的?就宛如,我们学计算机时,计算机处理的信息全部都是二进制,当我们问那图片,视频,怎么运作的在计算机?老师统统告是二进制。虽然我们知道二进制是0011这种形式,但是不是仍然有种想钻到计算机中,探个究竟,想真实的体会,或亲眼见识一下?
所以呢,把抽象的东西具体化,在真实的环境中再现,这样才能深入理解其中的原理。
那我们前面也说过,我们传入一个参数为int的方法,其实就是一段soap消息。那一个我们自定义对象,是如何传递呢?User对象在生成的wsdl中,其实是这样的一段代码:
<xs:complexType name="User"> <xs:sequence> <xs:element minOccurs="0" name="age" typke="xs:int" /> <xs:element minOccurs="0" name="id" type="xs:long" /> <xs:element minOccurs="0" name="name" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType>
再复杂的对象,实际上也是有基本类型组成。那我们看一下再调用时,传递的soap消息是如何的?
那接下来进入我们的正题,对于复杂类型参数传递。
我们实际上使用axiom方式调用服务。这种方式,同时也是Axis2的不同于Axis的一个新特性。
首先我们拿一个例子做测试,深入剖析返回内部的传递。
第一:测试返回值为自定义对象User对象。
服务器端,还是按照上传的文档开发。方法如下:
public User getUser() { User u= new User(); u.setId(100); u.setName( "123ee"); return u; }
那客户端调用方式如下:
public static void main(String[] args) throws Exception { EndpointReference targetEPR = new EndpointReference("http://localhost:8080/testWSServerByAxis2/services/myService?wsdl" ); try { Options options = new Options(); options.setTo(targetEPR); //加载目标服务器 ServiceClient sender = new ServiceClient(); sender.setOptions(options); OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://test.com" , "" ); //调用服务端的方法 OMElement method = fac.createOMElement("getUser" , omNs); //给方法赋值参数值 //method.addChild(sayHello); //返回OMElement对象 OMElement result = sender.sendReceive(method); System. out.println( "clientResult="+result); Iterator iterator=result.getChildElements(); while(iterator.hasNext()){ System. out.println( "ok"); OMNode omNode = (OMNode) iterator.next(); if(omNode.getType()==omNode. ELEMENT_NODE){ OMElement omElement = (OMElement) omNode; System. out.println( "***="+omElement.getLocalName()); if (omElement.getLocalName().toLowerCase().equals("return" )) { User u = (User) BeanUtil.processObject(omElement, User. class, null, true, new DefaultObjectSupplier()); System. out.println(u.getName()); } } } } catch (Exception e) { e.printStackTrace(); } }
[align=left] 那给大家看一下,客户端调用服务器端的getUser方法,返回来的是个OMElement对象。在上篇博客中的RPC调用方式中,直接返回的是无法转化User对象,提示OmElement对象无法转化成User对象。[/align]
[align=left] 好,我们看一下,服务器给客户端返回的是什么?注意这句代码的输出:[/align]
System. out.println( "clientResult="+result); clientResult=<ns:getUserResponse xmlns:ns="http://test.com"><ns:return xmlns:ax21="http://entity.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:User"><ax21:age>0</ax21:age><ax21:id>100</ax21:id><ax21:name>123ee</ax21:name></ns:return></ns:getUserResponse>
[align=left] 返回值是个soap消息,soap消息怎么会这样呢?为何不是那样的呢?他是根据什么来呢?为何是"http://test.com",又为何是ax21?大家对输出的信息是否也感到好奇呢?的确,我开始也是很好奇,那请跟着我的思路走,慢慢寻找答案。[/align]
[align=left] 咦,突然发现http://test.com跟代码中的fac.createOMNamespace("http://test.com" , "" );有关联,哦,原来是命名空间呢。说道命名空间,不知道大家是否有点明白?嘻嘻,命名空间是从哪里来?是从wsdl来啊?对,返回的soap消息格式是根据服务端的wsdl信息生成的。那我们在仔细研究一下我们服务端生成的wsdl。[/align]
[align=left] wsdl截取了重要的一部分,跟大家解释一下其中的关键处。[/align]
[align=left] 通过wsdl,我们就稍微明白服务器返回值信息。[/align]
[align=left]
[/align]
[align=left] 那下一步就是如何从返回值soap信息中抽取想要的User对象?[/align]
[align=left] 其实我们就想要返回值信息中age,id信息。那我们脑子中第一个想法是什么呢?我们该如何取到呢?[/align]
[align=left] 好,也许我们第一反应是,解析xml。类似java中的dom方式,解析xml。然后把相应的值,再拼接成User对象。[/align]
[align=left] 恭喜你。答对了,思路确实如此的。[/align]
[align=left] 但是,Axiom方式,不用我们一个个解析,然后自己去拼接。在Axiom中,自动会跟我们拼接成相应的对象,只要你告诉Axiom从哪到哪拼接完毕即可。[/align]
[align=left] 继续观察服务器给我们返回的信息,看一下,我们想从那拼接成User对象?[/align]
[align=left] 实际上,我们是想把<ax21:age>0</ax21:age><ax21:id>100</ax21:id><ax21:name>123ee</ax21:name>放到一个User对象中,可是Axiom是需要把一个整体标签中的东西封装,是寻找一个大标签,然后把其中的信息打包成用户想要的对象。而不是一个个查找。[/align]
[align=left] 这样的话,应该是这个User信息的外边一层标签。就是<ns:return></ns:return>[/align]
[align=left]
[/align]
[align=left] 若是明白这个道理的话,那么我们Axiom方式调用就理解了。[/align]
User u = (User) BeanUtil.processObject(omElement,
User. class, null, true, new DefaultObjectSupplier());
[align=left] [/align]
[align=left] OK,讲到这,不知是否明白其中的原理了?若是懂这个例子的话,那么返回值是List<User>也是很简单了,直接用List.add(u)即可。然后返回值为list就有了。[/align]
[align=left] 这节课讲的是返回值为List对象,这样的话,服务器端不用改动。客户端调用方式不使用RPC方式,而是使用Axiom,当然这种肯定也支持RPC支持的基本类型。那下节课给大家深入讲解传递参数为复杂定义类型。[/align]
相关文章推荐
- 深入剖析Axis2中参数为复杂自定义类型值【步步逼近实践篇】
- 深入Atlas系列:Web Sevices Access in Atlas示例(5) - 自定义TypeConverter把基础类型转换为复杂类型
- 使用自定义JavaScriptConverter返回自定义的复杂类型
- 深入Atlas系列:Web Sevices Access in Atlas示例(5) - 自定义TypeConverter把基础类型转换为复杂类型
- Axis2传递、返回复杂类型的对象
- 深入Atlas系列:Web Sevices Access in Atlas示例(5) - 自定义TypeConverter把基础类型转换为复杂类型
- NAT类型及转换原理深入剖析
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(一)
- 深入Atlas系列:Web Sevices Access in Atlas(4) - 对于复杂数据类型的支持(上)
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
- 传递、返回复杂类型的对象
- 【Hibernate】hibernate原生sql利用transformers返回多表自定义类型对象
- 使用Hibernate返回自定义类型时报错的问题
- springMVC 参数传递之:数组,Map,List,Set以及自定义复杂类型参数
- Struts2自定义返回Json类型result
- [Silverlight]WCF RIA SERVICE如何返回自定义类型(非Entity)
- 深入Atlas系列:Web Sevices Access in Atlas(4) - 对于复杂数据类型的支持(上)
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
- 关于Java中的注解类型深入剖析
- PL/SQL 基础---复杂数据类型和自定义类型