Web Service 学习总结(三)

Web Service框架

Java常用的Web Service框架有Apache CXF和Axis2。在网上查了下,大概有以下不同。

  • Apache CXF 是根据Spring哲学来进行编写的,即可以无缝地与Spring进行整合,而Axis2不能。
  • Axis2支持多语言-除了Java,他还支持C/C++版本,CXF仅支持Java。
  • Axis2允许自己作为独立的应用来发布Web Service,并提供了大量的功能和一个很好的模型,这个模型可以通过它本身的架构(modular architecture)不断添加新的功能。
  • CXF更注重开发人员的工效(ergonomics)和嵌入能力(embeddability)。CXF强调代码优先的设计方式(code-first design),使用了简单的API使得从现有的应用开发服务变得方便。

Axis2调用WS

上次仅用JDK就实现了WS的调用。这次用Axis2来调用WS。

Axis2的下载地址: http://axis.apache.org/axis2/java/core/download.cgi

下载的Jar包(axis2-1.6.0-bin.zip)导入到自己建的Project中就可以使用了。不过实际开发中更多的是用Maven导入Jar包的。pom.xml文件的dependencies标签中加入以下dependency标签就可以了。

<dependency>
	<groupId>org.apache.axis2</groupId>
	<artifactId>axis2-spring</artifactId>
	<version>${axis2.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.axis2</groupId>
	<artifactId>axis2-transport-http</artifactId>
	<version>${axis2.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.axis2</groupId>
	<artifactId>axis2-transport-local</artifactId>
	<version>${axis2.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.axis2</groupId>
	<artifactId>axis2-xmlbeans</artifactId>
	<version>${axis2.version}</version>
</dependency>

上面的version定义:

<properties>
	<axis2.version>1.7.8</axis2.version>
</properties>

Java代码:

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.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.apache.axis2.engine.DefaultObjectSupplier;

public class HelloWorldClientTest2 {
	public static void main(String[] args) throws AxisFault {
		ServiceClient serviceClient = new ServiceClient();
		// WebService URL
		String url = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx";
		EndpointReference targetEPR = new EndpointReference(url);
		Options options = serviceClient.getOptions();
		options.setExceptionToBeThrownOnSOAPFault(false);
		options.setTo(targetEPR);
		// WSDLファイルのtargetNameSpace+method
options.setAction("http://WebXml.com.cn/getMobileCodeInfo");
		
		OMFactory fac = OMAbstractFactory.getOMFactory();
		// NameSpace
		OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn/", "");
		OMElement method = fac.createOMElement("getMobileCodeInfo", omNs);
		// 参数设定
		OMElement phone = fac.createOMElement("phone", omNs);
		phone.setText("18765336141");
		method.addChild(phone);
		OMElement userId = fac.createOMElement("userId", omNs);
		userId.setText("");
		method.addChild(userId);
		
		method.build();
		
		// WSを呼び出す
		OMElement response = serviceClient.sendReceive(method);
		System.out.println(response);
		Object[] result = BeanUtil.deserialize(response, new Class[] {String.class},
                new DefaultObjectSupplier());
		System.out.println(result[0]);
	}
}

和上次的代码最大的不同是不需要构建XML和解析XML,这些都由OMElement类实现了。返回结果用框架的BeanUtil.deserialize()解析了。更一般的方法是遍历XML节点(OMNode)取得结果。

可以把上面的代码做成共同方法,调用时其实只需要指定Web Service的名和想调用的方法名,以及设定的参数就行了。返回值如果是复杂数据类型的话,可以单独定义一个类来保持返回值。