利用SOAPUI工具执行webservice


soapui是一个webservice的测试工具。他提供图形界面编辑soap格式的数据然后post到服务端,返回soap数据,

阅读以下他的源码以后可以利用的这个工具来做一个调用webservice的动态客户端。

虽然说现在webservice的客户端调用比较方便,axis的话可以利用eclipse插件建一个webservice client代码自动生成,cxf 也可以利用wsdl2java生成客户端。

但是这2种方式都避免不了需要构建class加载到classloader里面,如果一个应用需要调用大量的webservice的话,那么这些class的数量相当可观,应用也因为webservice而庞大起来。

那么利用SOAPUI 写一个动态客户端,说白了就是构建soap数据,利用httpclient 发送 soap数据,处理返回soap数据。

直接上代码剖析:

jar包列表(soapui不是省油的灯,依赖的jar确实不少,删减了好多才找到减少到这么多),ps:如果肯下狠心把内容提取一下应该不错,可惜没有那个魄力了。



QQ截图20130407095000           QQ截图20130407095353

博客不能上传jar包,分享代码容量也不够,可惜~~。

首先编写帮助类,利用SOAPUI 获取需要执行的webservice的信息

package com.test.share.soapui;

import java.io.IOException;

import org.apache.xmlbeans.XmlException;

import com.eviware.soapui.impl.WsdlInterfaceFactory;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
import com.eviware.soapui.support.SoapUIException;

/**
 * 
 * @author fat_tian
 *
 */
public class SoapUIHelper {
	/**
	 * 获取webservice信息类 
	 * @param wsdl
	 * @param opName
	 * @return
	 * @throws SoapUIException
	 * @throws XmlException
	 * @throws IOException
	 */
	public static WsdlOperation getWsdlFace(String wsdl,String opName) throws SoapUIException, XmlException, IOException{

		//根据wsdl地址获取接口
		WsdlInterface[] facesInfo=WsdlInterfaceFactory.importWsdl(new WsdlProject(), wsdl, false);
		
		if(facesInfo!=null&&facesInfo.length>0){
//			根据接口获取方法
			for(WsdlInterface wface: facesInfo){
				//获取soap1.1的吧~
				if(SoapVersion.Soap11.equals(wface.getSoapVersion())){
					WsdlOperation op =wface.getOperationByName(opName);
					return op;
				}
			}
		}
		return null;
	}
	
	
	

}


好,接下来就是webservice执行器

package com.test.share.soapui;


import java.util.Date;

import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;

import org.apache.commons.lang.StringUtils;

import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.WsdlSubmit;
import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
import com.eviware.soapui.model.iface.Response;
import com.eviware.soapui.model.iface.SubmitContext;

/**
 * 
 * @author fat_tian
 *
 */
public class SoapUIExecutor {

	private SoapProxy proxy;
	
	public SoapUIExecutor(SoapProxy proxy){
		this.proxy=proxy;
	}
	/**
	 * 通过SOAPUI 获取到需要调用webservice信息
	 * @param wsdl 
	 * @param opName 方法名
	 * @return 
	 * @throws Exception
	 */
	private WsdlOperation getWsdlOperation(String wsdl,String opName) throws Exception{
		
		WsdlOperation wop=SoapUIHelper.getWsdlFace(wsdl, opName);
		return wop;
	}
	
	/**
	 * 执行webservice
	 * 执行顺序逻辑:
	 * doBefore执行前-->parsePostData数据转换-->submitData提交--parseRtnData数据转化-->doAfter执行后
	 */
	public String processWs(String wsdl,String opName){
		try{
//			执行前搞些啥~~
		doBefore();
//		获取执行方法信息
		WsdlOperation op=getWsdlOperation(wsdl, opName);
		
		if(op==null){
			throw new Exception("operante is null~");
		}
//		获取soap格式数据
		String opData=getDataTemplate(op);
		
		if(StringUtils.isEmpty(opData)){
			throw new Exception("soap data is null ~");
		}
//		对soap格式数据进行数据填充之类。。。
		opData =parsePostData(opData);
//		提交数据(执行webservice了)
		String response =submitData(opData, op);
//		处理返回数据
		 response=parseRtnData(response);
//		执行后搞些啥~~
		doAfter();
		
		return response;
		}catch (Exception e) {
			// TODO: handle exception
			doError(e);
		}finally{
			
		}
		return null;
	}
	
	private String submitData(String opData,WsdlOperation operation) throws Exception{
		
		WsdlRequest  request=operation.addNewRequest("ws_"+new Date().getTime());
		SubmitContext context = new WsdlSubmitContext(request);
		
		request.setRequestContent(opData);
		WsdlSubmit<WsdlRequest> submit = (WsdlSubmit<WsdlRequest>) request
				.submit(context, false);
		Response response = submit.getResponse();
		// 获取了返回的输出参数的XML
		String resData = response.getContentAsString();
		
		return resData;
	}
	
	
	private String getDataTemplate(WsdlOperation operation) throws Exception{
		//获取webservice 接口 
		WsdlInterface face= operation.getInterface();
//		获取到soap数据的builder
		SoapMessageBuilder builder = face.getMessageBuilder();
		Definition definition = face.getWsdlContext().getDefinition();
//		找到方法
		BindingOperation bo = operation.findBindingOperation(definition);
//		构建soap格式数据。。。
		String soapData = builder.buildSoapMessageFromInput(bo, true, true);
		return soapData;
	}
	
	
	private String parsePostData(String soapTemplate){
		
		//这里可以对这个xml进行操作~从而达到赋值的效果,这里需要下手写多点代码了做数据绑定
		//让代理去搞
		return proxy.parsePostData(soapTemplate);
	}
	
	private String parseRtnData(String data){
		
//		这里可以对返回值进行处理,组装符合业务需求的xml
		//让代理去搞
		return proxy.parseRtnData(data);
	}
	
	private  void doBefore(){
		//让代理去搞
		proxy.doBefore();
	};
	
	private  void doAfter(){
		//..
		proxy.doAfter();
	}
	
	private  void doError(Exception e){
		//...
		proxy.doError(e);
	}
	
	
	
	
}


下面贴个简单的代理类,这个代码如果可以做数据绑定的话将会是一个强大的代理类哦~

package com.test.share.soapui;

/**
 * 执行soap的一个代理
 * @author fat_tian
 *
 */
public class SoapProxy {

	public String parsePostData(String soapTemplate) {
		
		System.out.println(soapTemplate);
		return soapTemplate;
	}
	public String parseRtnData(String data) {

		System.out.println(data);
		return data;
	}

	public void doBefore() {
		System.out.println(" doBefore~ ");
	};

	public void doAfter() {
		System.out.println(" doAfter~ ");
	};

	public void doError(Exception e) {
		System.out.println(e.getMessage());
	};

}


ok,以上就完成了整个执行的类,下面简单调用一个天气预报的webservice来做尝试

package com.test.share.soapui;

public class Test {
	public static void main(String[] args) throws Exception {

		SoapUIExecutor exec = new SoapUIExecutor(new SoapProxy());

		String rtn = exec
				.processWs(
						"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl",
						"getSupportProvince");

	}
}

你可能感兴趣的:(java,webservice,SOAPUI)