bsp; 由于我们采用的是双工模式,因此需要寻址:engageModule
这个engageModule就是需要访问你的工程的WEB-INF\modules\目录下的一个叫addressing-1.4.mar的文件。
因此在调用engageModule语句之间有两种方式来调用你的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()指定第一个sysContext参数,但是,你必须把WEB-INF\modules\addressing-1.4.mar指定到你的工程的classpath中去,如下图
要不然运行时会抛出下面这个exception:
org.apache.axis2.AxisFault:Unable to engage module : addressing
1) 使用非阻塞方式调用:sendReceiveNonBlocking(方法, callback类)
最后我们在CallBack具体的实类中我们巧妙使用了线程的wait()和notify()来实现“阻塞”。
3.2 再来看如何解析返回的值
由于返回的值也是一个OMElement结构体,来看SOAP UI工具中给我们生成的返回结果
<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
其实,我们需要做的就是解析这个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的世界中,这个namespace很重要,相当于一个头标记,如果我们在调用下面这句话时
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。
相信,经过这样的讲解,因该能够使你看得懂一个Axis2的API客户端了吧,从此处我们可以发觉,很多语句都是“固化”的,和EJB的调用一样,一堆固化的语句,写多了,理解起来就并不难了,呵呵。
四、复杂类型的Webservice
更多的时候,我们的Service需要返回类似于List<Person>, List<String>这样的数据结构,因为有时我们先要在server端通过数据库取值,然后再把值返回给客户端,我们就一起来看如何生成一个具有复杂类型的Web Service以及它相应的客户端调用的写法吧。
下面是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&