通向架构师的道路(第十一天)之Axis2 Web Service(二)
一、總結(jié)前一天
前一天中我們講述了如何生成一個(gè)Axis2的WebService, 如何布署以及4種不同的客戶端, 它們是: 傳統(tǒng)式, 非阻塞式, 雙工模式, 雙工非阻塞。
并且我們看到了一個(gè)Axis2的Web Service的布署描述:
| <service name="HelloWorld"> ???????? <parameter name="ServiceClass">org.sky.axis2.helloworld.HelloWorld</parameter> ??? <operation name="sayHello"> <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> ??????? <actionMapping>urn:sayHello</actionMapping> ??? </operation> </service> |
這個(gè)描述代表我們的這個(gè)Web Service的方法有一進(jìn)一出兩個(gè)參數(shù),且是Axis2特有的” OMElement”類型。
那么,我們想要一個(gè)public String sayHello(String name)這樣的一種簡(jiǎn)單的Java類型來書寫我們的WebService可以嗎?
當(dāng)然,只不過我們的布署描述和我們的客戶端調(diào)用返回值上稍稍有一些不一樣。
二、使用簡(jiǎn)單Java類型書寫我們的WebService
HelloJava類:
| package org.sky.axis2.helloworld.javatype; import javax.xml.stream.XMLStreamException; import org.apache.axiom.om.OMElement; public class HelloJava { ???????? public String sayHello(String name) throws XMLStreamException { ?????????????????? StringBuffer hello = new StringBuffer(); ?????????????????? hello.append("hello: "); ?????????????????? hello.append(name); ?????????????????? return hello.toString(); ???????? } } |
Service描述文件:
此時(shí)我們相應(yīng)的布署文件就是service.xml文件內(nèi)容稍稍不一樣,來看
| <service name="HelloJava"> ???????? <parameter name="ServiceClass" locked="false"> ?????????????????? org.sky.axis2.helloworld.javatype.HelloJava ???????? </parameter> ???????? <messageReceivers> ?????????????????? <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" ??????????????????????????? class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> ???????? </messageReceivers> ???????? <actionMapping>urn:sayHello</actionMapping> </service> |
我們把這個(gè)WebService布署入Tomcat后啟動(dòng)起來看
是不是多了一個(gè)Service叫”HelloJava”。
我們把這個(gè)Service的wsdl地址導(dǎo)入SOAP UI工具并生成模擬客戶端,然后再來看看它的調(diào)用與返回值。
注意這個(gè)返回值:
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> ?? <soapenv:Body> ????? <ns:sayHelloResponse xmlns:ns="http://javatype.helloworld.axis2.sky.org"> ????????<ns:return>hello: Simon Shen</ns:return> ????? </ns:sayHelloResponse> ?? </soapenv:Body> </soapenv:Envelope> |
標(biāo)有紅色加粗的部分,反正一粗,就有用就是好東西(我喜歡粗,YEAH)。
再來比較一下昨天我們用“org.apache.axis2.receivers.RawXMLINOutMessageReceiver”這個(gè)Service描述生成的返回值
org.apache.axis2.receivers.RawXMLINOutMessageReceiver
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> ?? <soapenv:Body> ????? <hel:sayHello xmlns:hel="http://helloworld.axis2.sky.org"> ???????? <!--Optional:--> ?????????<hel:sayHello>Monica</hel:sayHello> ????? </hel:sayHello> ?? </soapenv:Body> </soapenv:Envelope> |
看到區(qū)別沒有?于是,更改我們的客戶端調(diào)用代碼如下,在此我們使用異步雙工模式:
org.sky.axis2.helloworld.javatype.HelloJavaWithReturnDualNonBlock
| package org.sky.axis2.helloworld.javatype; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; public class HelloJavaWithReturnDualNonBlock { ???????? private static EndpointReference targetEPR = new EndpointReference( ??????????????????????????? "http://localhost:8080/Axis2Service/services/HelloJava"); ???????? public static boolean finish = false; ???????? public void sayHello() { ?????????????????? OMFactory fac = OMAbstractFactory.getOMFactory(); ?????????????????? OMNamespace omNs = fac.createOMNamespace( ???????????????????????????????????? "http://javatype.helloworld.axis2.sky.org", ""); ?????????????????? OMElement method = fac.createOMElement("sayHello", omNs); ?????????????????? OMElement name = fac.createOMElement("name", omNs); ?????????????????? name.setText("ymk"); ?????????????????? method.addChild(name); ?????????????????? method.build(); ?????????????????? Options options = new Options(); ?????????????????? options.setTo(targetEPR); ?????????????????? options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ?????????????????? options.setUseSeparateListener(true); ?????????????????? options.setAction("urn:sayHello"); ?????????????????? ServiceClient sender = null; ???????????????????HelloJavaNonBlockCB callback = new HelloJavaNonBlockCB(); ?????????????????? try { ??????????????????????????? sender = new ServiceClient(); ??????????????????????????? sender.engageModule(Constants.MODULE_ADDRESSING); ??????????????????????????? sender.setOptions(options); ??????????????????????????? sender.sendReceiveNonBlocking(method, callback); ??????????????????????????? synchronized (callback) { ???????????????????????????????????? try { ????????????????????????????????????????????? callback.wait(); ???????????????????????????????????? } catch (InterruptedException e) { ?????????????????????????????????????????????? e.printStackTrace(); ???????????????????????????????????? } ??????????????????????????? } ?????????????????? } catch (Exception e) { ??????????????????????????? e.printStackTrace(); ?????????????????? } finally { ??????????????????????????? try { ???????????????????????????????????? sender.cleanup(); ??????????????????????????? } catch (Exception e) { ??????????????????????????? } ?????????????????? } ???????? } ???????? public static void main(String[] args) { ?????????????????? HelloJavaWithReturnDualNonBlock testClient = new HelloJavaWithReturnDualNonBlock(); ?????????????????? testClient.sayHello(); ???????? } } |
相關(guān)的CallBack類,org.sky.axis2.helloworld.javatype.HelloJavaNonBlockCB:
| package org.sky.axis2.helloworld.javatype; import java.util.Iterator; import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axis2.client.async.AxisCallback; import org.apache.axis2.context.MessageContext; import org.apache.axis2.databinding.utils.BeanUtil; import org.apache.axis2.engine.DefaultObjectSupplier; public class HelloJavaNonBlockCB implements AxisCallback { ???????? private boolean complete = false; ???????? public void onMessage(MessageContext msgContext) { ?????????????????? System.out.println(msgContext.getEnvelope().getBody()); ?????????????????? OMElement element = msgContext.getEnvelope().getBody() ???????????????????????????????????? .getFirstElement(); ???????????????????OMElement result = element.getFirstChildWithName(new QName( ?????????????????????????????????????"http://javatype.helloworld.axis2.sky.org", "return")); ?????????????????? System.out.println(result.getText()); ?????????????????? synchronized (this) { ??????????????????????????? this.notify(); ?????????????????? } ???????? } ???????? public boolean isComplete() { ?????????????????? return complete; ???????? } ???????? public void onFault(MessageContext msgContext) { ?????????????????? System.out.println(msgContext.getEnvelope().getBody().getFault() ???????????????????????????????????? .toString()); ?????????????????? synchronized (this) { ??????????????????????????? this.notify(); ?????????????????? } ???????? } ???????? public void onError(Exception e) { ?????????????????? e.printStackTrace(); ?????????????????? synchronized (this) { ??????????????????????????? this.notify(); ?????????????????? } ???????? } ???????? public void onComplete() { ?????????????????? this.complete = true; ?????????????????? synchronized (this) { ??????????????????????????? this.notify(); ?????????????????? } ???????? } } |
下面是客戶端運(yùn)行后的輸出:
注意在CallBack類中的這一句:
OMElement result = element.getFirstChildWithName(new QName(
?????????????????????????????????????"http://javatype.helloworld.axis2.sky.org","return"));
和下面這個(gè)SOAP UI的返回值來作個(gè)比較“注意這個(gè)Return”
“<ns:return>hello: Simon Shen</ns:return>”
三、深入理解Axis2的API的寫法
我們一邊看著SOAP UI給我們生成的調(diào)用端和結(jié)果來看這些個(gè)API。
Axis2中的一切都是一種OMElement,它其實(shí)就是一個(gè)“XML”結(jié)構(gòu)的Java對(duì)象。
3.1?先來看調(diào)用端的生成
下面是Soap UI幫我們生成的客戶端
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jav="http://javatype.helloworld.axis2.sky.org"> ?? <soapenv:Header/> ?? <soapenv:Body> ????? <jav:sayHello> ???????? <!--Optional:--> ???????? <jav:name>Simon Shen</jav:name> ????? </jav:sayHello> ?? </soapenv:Body> </soapenv:Envelope> |
通過上述的內(nèi)容我們可以知道,調(diào)用一個(gè)以wsdl方式暴露的Web Service的客戶端需要下面這些元素:
1)????? 調(diào)用地址 end point
| private static EndpointReference targetEPR = new EndpointReference( ??????????????????? "http://localhost:8080/Axis2Service/services/HelloJava"); |
2)????? Web Service方法,注意service.xml描述中的這一行
| <actionMapping>urn:sayHello</actionMapping> |
這個(gè)被稱為我們的Web Method,它指向了我們?cè)陬愔械?#xff1a;
| public String sayHello(String name) throws XMLStreamException { |
該方法有一個(gè)返回,一個(gè)進(jìn)參,返回已經(jīng)我們的service.xml描述中用:
| <messageReceivers> ??????????? <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" ???????????????????? class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> </messageReceivers> |
它的進(jìn)參我們假設(shè)是一個(gè)String類型的。
這樣一個(gè)Web Method的原始調(diào)用(其實(shí)我們把它稱為SOAP調(diào)用)應(yīng)該是如SOAP UI工具中給我們生成的語句那樣:
| <jav:sayHello> ???????? <!--Optional:--> ???????? <jav:name>Simon Shen</jav:name> ??? </jav:sayHello> |
因此,為了生成上述的SOAP語句,我們采Axis2的API書寫如下,下面的代碼的效果將會(huì)在程序運(yùn)行時(shí)產(chǎn)生等同于上面的SOAP調(diào)用語句,一起來看看:
| OMFactory fac = OMAbstractFactory.getOMFactory(); ?????????? OMNamespace omNs = fac.createOMNamespace( ???????????????????????????? "http://javatype.helloworld.axis2.sky.org", ""); ?????????? OMElement method = fac.createOMElement("sayHello", omNs); ?????????? OMElement name = fac.createOMElement("name", omNs); ?????????? name.setText("ymk"); ?????????? method.addChild(name); ???????????????????method.build(); |
當(dāng)”method.build()”命令發(fā)出后,上述這些API就生成SOAP調(diào)用語句,去調(diào)用”sayHello”這個(gè)方法,然后往里面?zhèn)魅肓艘粋€(gè)String類型的值。
可以看到,這個(gè)API非常像dom4j的語句,只是這邊不是一個(gè)document類型而是一個(gè)類XML的OMElement結(jié)構(gòu)體,都是addChild, setText之類的,對(duì)吧?
再繼續(xù)往下看我們的API
| Options options = new Options(); ?????????? options.setTo(targetEPR); ?????????? options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ?????????? options.setUseSeparateListener(true); ?????????????????? options.setAction("urn:sayHello"); |
1)????? 將該web method的調(diào)用指向指定的end point
2)????? 開啟雙工模式
3)????? 因?yàn)槭请p工模式,需要在client端開啟一個(gè)監(jiān)聽器
4)????? 設(shè)置調(diào)用的web method為”urn:sayHello”
| sender = new ServiceClient(); ??????????????????????????? sender.engageModule(Constants.MODULE_ADDRESSING); ??????????????????????????? sender.setOptions(options); ??????????????????????????? sender.sendReceiveNonBlocking(method, callback); |
1)????? 生成調(diào)用句柄
2)????? 由于我們采用的是雙工模式,因此需要尋址:engageModule
這個(gè)engageModule就是需要訪問你的工程的WEB-INF\modules\目錄下的一個(gè)叫addressing-1.4.mar的文件。
因此在調(diào)用engageModule語句之間有兩種方式來調(diào)用你的WEB-INF\modules目錄下的addressing-1.4.mar文件。
第一種方式:
| ConfigurationContext sysContext = ConfigurationContextFactory ?????????????????????????????????????? .createConfigurationContextFromFileSystem( ???????????????????????????????????????????????????????? "D:\\wspace\\Axis2Service\\WebContent\\WEB-INF", ???????????????????????????????????????????????????????? null); ????????????????????sender = new ServiceClient(sysContext, null); ??????????????????????????? sender.engageModule(Constants.MODULE_ADDRESSING); |
第二種方式:
| sender = new ServiceClient(sysContext, null); ???????? sender.engageModule(Constants.MODULE_ADDRESSING); |
在第二種方式中,不需要為new ServiceClient()指定第一個(gè)sysContext參數(shù),但是,你必須把WEB-INF\modules\addressing-1.4.mar指定到你的工程的classpath中去,如下圖
要不然運(yùn)行時(shí)會(huì)拋出下面這個(gè)exception:
org.apache.axis2.AxisFault:Unable to engage module : addressing
1)????? 使用非阻塞方式調(diào)用:sendReceiveNonBlocking(方法, callback類)
最后我們?cè)贑allBack具體的實(shí)類中我們巧妙使用了線程的wait()和notify()來實(shí)現(xiàn)“阻塞”。
3.2?再來看如何解析返回的值
由于返回的值也是一個(gè)OMElement結(jié)構(gòu)體,來看SOAP UI工具中給我們生成的返回結(jié)果
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> ?? <soapenv:Body> ????? <ns:sayHelloResponse xmlns:ns="http://javatype.helloworld.axis2.sky.org"> ???????? <ns:return>hello: Simon Shen</ns:return> ????? </ns:sayHelloResponse> ?? </soapenv:Body> </soapenv:Envelope> |
其實(shí),我們需要做的就是解析這個(gè)SOAP的返回包(soap response)。
| public void onMessage(MessageContext msgContext) { ?????????????????? System.out.println(msgContext.getEnvelope().getBody()); ?????????????????? OMElement element = msgContext.getEnvelope().getBody() ???????????????????????????????????? .getFirstElement(); ?????????????????? OMElement result = element.getFirstChildWithName(new QName( ???????????????????????????????????? "http://javatype.helloworld.axis2.sky.org", "return")); ?????????????????? System.out.println(result.getText()); ?????????????????? synchronized (this) { ??????????????????????????? this.notify(); ?????????????????? } } |
在SOAP的世界中,這個(gè)namespace很重要,相當(dāng)于一個(gè)頭標(biāo)記,如果我們?cè)谡{(diào)用下面這句話時(shí)
| OMElement result = element.getFirstChildWithName(new QName( ???????????????????????????????????? "http://javatype.helloworld.axis2.sky.org", "return")); |
沒有加http://javatype.helloworld.axis2.sky.org,那么這段soapresponse將無法被正確定位到
| <ns:return>hello: Simon Shen</ns:return> |
那么你將得到NullPointerException。
相信,經(jīng)過這樣的講解,因該能夠使你看得懂一個(gè)Axis2的API客戶端了吧,從此處我們可以發(fā)覺,很多語句都是“固化”的,和EJB的調(diào)用一樣,一堆固化的語句,寫多了,理解起來就并不難了,呵呵。
四、復(fù)雜類型的Webservice
更多的時(shí)候,我們的Service需要返回類似于List<Person>, List<String>這樣的數(shù)據(jù)結(jié)構(gòu),因?yàn)橛袝r(shí)我們先要在server端通過數(shù)據(jù)庫取值,然后再把值返回給客戶端,我們就一起來看如何生成一個(gè)具有復(fù)雜類型的Web Service以及它相應(yīng)的客戶端調(diào)用的寫法吧。
下面是Service端:
org.sky.axis2.javacomplextype.PersonService
| package org.sky.axis2.javacomplextype; import org.apache.axiom.om.OMElement; import org.apache.axis2.databinding.utils.BeanUtil; import java.util.*; import javax.xml.namespace.QName; public class PersonService { ???????? public OMElement getPersons(OMElement person) { ?????????????????? Person man = new Person(); ?????????????????? List<Person> list = new ArrayList<Person>(); ?????????????????? man.setName("Wallance Shao"); ?????????????????? man.setAge("25"); ?????????????????? list.add((Person) man.clone()); ?????????????????? man.setAge("11"); ?????????????????? man.setName("Hong Wayne"); ?????????????????? list.add((Person) man.clone()); ?????????????????? OMElement omElement = BeanUtil.getOMElement(new QName("root"), ???????????????????????????????????? list.toArray(), new QName("person"), false, null); ?????????????????? return omElement; ???????? } } |
它生成了一個(gè)List<Person>的復(fù)雜類型,它的返回類型必須為OMElement結(jié)構(gòu),下面再來看Person.java類:
org.sky.axis2.javacomplextype.Person
| package org.sky.axis2.javacomplextype; import java.io.*; public class Person implements Serializable,Cloneable{ ???????? private String name=""; ???????? private String age=""; ???????? public String getName() { ?????????????????? return name; ???????? } ???????? public void setName(String name) { ?????????????????? this.name = name; ???????? } ???????? public String getAge() { ?????????????????? return age; ???????? } ???????? public void setAge(String age) { ?????????????????? this.age = age; ???????? } ???????? public Object clone(){ ?????????????????? Object o = null; ?????????????????? try{ ??????????????????????????? o=super.clone(); ?????????????????? }catch(Exception e){ ??????????????????????????? e.printStackTrace(); ??????????????????????????? o=null; ?????????????????? } ?????????????????? return o; ???????? } } |
它的內(nèi)容如下:
| <service name="PersonService"> ???????? <parameter name="ServiceClass">org.sky.axis2.javacomplextype.PersonService</parameter> ??? <operation name="getPersons"> ??????? <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> ??????? <actionMapping>urn:getPersons</actionMapping> ??? </operation> </service> |
把它布署進(jìn)我們的tomcat,啟動(dòng)后可以得到一個(gè)新的service
書寫我們的客戶端,此處我們使用非阻塞式寫法。
注意:
把Server端的Person.java拷貝一份到客戶端的package中去,一定記得,要不然造型時(shí)會(huì)出錯(cuò)
org.sky.axis2.javacomplextype.PersonServiceClient
| package org.sky.axis2.javacomplextype; import java.util.Iterator; import javax.xml.namespace.QName; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.client.async.AxisCallback; import org.apache.axis2.context.MessageContext; public class PersonServiceClient { ???????? private static EndpointReference targetEPR = new EndpointReference( ??????????????????????????? "http://localhost:8080/Axis2Service/services/PersonService"); ???????? public void getPersons() { ?????????????????? Options options = new Options(); ?????????????????? options.setAction("urn:getPersons"); ?????????????????? options.setTo(targetEPR); ?????????????????? options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ?????????????????? options.setUseSeparateListener(true); ?????????????????? ServiceClient sender = null; ?????????????????? try { ??????????????????????????? PersonCallBack callback = new PersonCallBack(); ??????????????????????????? sender = new ServiceClient(); ??????????????????????????? sender.setOptions(options); ??????????????????????????? sender.engageModule(Constants.MODULE_ADDRESSING); ??????????????????????????? OMFactory fac = OMAbstractFactory.getOMFactory(); ??????????????????????????? OMNamespace omNs = fac.createOMNamespace( ?????????????????????????????????????????????? "http://javacomplextype.axis2.sky.org", ""); ??????????????????????????? OMElement method = fac.createOMElement("getPersons", omNs); ??????????????????????????? OMElement person = fac.createOMElement("person", omNs); ??????????????????????????? person.setText(""); ??????????????????????????? method.addChild(method); ??????????????????????????? sender.sendReceiveNonBlocking(method, callback); ??????????????????????????? synchronized (callback) { ???????????????????????????????????? try { ?????????????????????????????????????????????? callback.wait(); ???????????????????????????????????? } catch (InterruptedException e) { ?????????????????????????????????????????????? e.printStackTrace(); ???????????????????????????????????? } ??????????????????????????? } ?????????????????? } catch (Exception e) { ??????????????????????????? System.out.println("-------Error Occured-------"); ??????????????????????????? e.printStackTrace(); ?????????????????? } finally { ??????????????????????????? try { ???????????????????????????????????? sender.cleanup(); ??????????????????????????? } catch (Exception e) { ??????????????????????????? } ?????????????????? } ???????? } ???????? public static void main(String[] args) { ?????????????????? PersonServiceClient testClient = new PersonServiceClient(); ?????????????????? testClient.getPersons(); ???????? } } |
由于是非阻塞式,因此需要寫CallBack具體實(shí)現(xiàn)類,下面是我們的CallBack具體實(shí)現(xiàn)類,注意紅色加粗部分為我們的核心代碼。
org.sky.axis2.javacomplextype.PersonCallBack
| package org.sky.axis2.javacomplextype; import java.util.Iterator; import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axis2.client.async.AxisCallback; import org.apache.axis2.context.MessageContext; import org.apache.axis2.databinding.utils.BeanUtil; import org.apache.axis2.engine.DefaultObjectSupplier; public class PersonCallBack implements AxisCallback { ???????? public void onMessage(MessageContext msgContext) { ???????????????????OMElement result = msgContext.getEnvelope().getBody().getFirstElement(); ???????????????????System.out.println("result====" + result); ???????????????????if (result == null) { ????????????????????????????return; ???????????????????} ???????????????????Iterator iterator = result.getChildElements(); ???????????????????while (iterator.hasNext()) { ????????????????????????????OMNode omNode = (OMNode) iterator.next(); ????????????????????????????if (omNode.getType() == OMNode.ELEMENT_NODE){ ?????????????????????????????????????OMElement omElement = (OMElement) omNode;
?????????????????????????????????????if (omElement.getLocalName().toLowerCase().equals("person")) { ??????????????????????????????????????????????try { ???????????????????????????????????????????????????????Person person = (Person) BeanUtil.processObject( ??????????????????????????????????????????????????????????????????????????omElement, Person.class, null, true, ??????????????????????????????????????????????????????????????????????????new DefaultObjectSupplier()); ???????????????????????????????????????????????????????System.out.println("person name=" + person.getName() ??????????????????????????????????????????????????????????????????????????+ " person age=" + person.getAge()); ??????????????????????????????????????????????} catch (Exception e) { ???????????????????????????????????????????????????????System.out.println("-------Error Occured-------"); ???????????????????????????????????????????????????????e.printStackTrace(); ??????????????????????????????????????????????} ???????????????????????????????????? } ??????????????????????????? } ?????????????????? } ?????????????????? synchronized (this) { ??????????????????????????? try { ???????????????????????????????????? this.notify(); ??????????????????????????? } catch (Exception e) { ??????????????????????????? } ?????????????????? } ???????? } ???????? public void onFault(MessageContext msgContext) { ?????????????????? System.out.println(msgContext.getEnvelope().getBody().getFault() ???????????????????????????????????? .toString()); ?????????????????? synchronized (this) { ??????????????????????????? try { ???????????????????????????????????? this.notify(); ??????????????????????????? } catch (Exception e) { ??????????????????????????? } ?????????????????? } ???????? } ???????? public void onError(Exception e) { ?????????????????? synchronized (this) { ??????????????????????????? try { ???????????????????????????????????? this.notify(); ??????????????????????????? } catch (Exception ex) { ??????????????????????????? } ?????????????????? } ?????????????????? e.printStackTrace(); ???????? } ???????? public void onComplete() { ?????????????????? synchronized (this) { ??????????????????????????? try { ???????????????????????????????????? this.notify(); ??????????????????????????? } catch (Exception e) { ??????????????????????????? } ?????????????????? } ???????? } } |
運(yùn)行我們的PersonServiceClient類,得到輸出如下:
完成我們Axis2的第二天的課程!!!
總結(jié)
以上是生活随笔為你收集整理的通向架构师的道路(第十一天)之Axis2 Web Service(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通向架构师的道路(第十天)之Axis2
- 下一篇: 通向架构师的道路(第十二天)之Axis2