当前位置: 代码迷 >> Web前端 >> SOAP模式实现Web Service动态客户端
  详细解决方案

SOAP模式实现Web Service动态客户端

热度:103   发布时间:2012-09-10 22:20:13.0
SOAP方式实现Web Service动态客户端

工作需要想要实现一个动态调用Web Service的客户端,希望不同的Web Service只需要提供出WSDL URI和需要的输入参数值,就可以方便的得到Web Service的输出结果。于是一直盘旋于AXIS和CXF的代码中,源码看了一大堆,办法想尽,实现无数,效果却不尽理想。



忽然想到,Web Service底层就是SOAP的XML格式的Request与Response,如果我组装好Request的XML,然后直接用SOAP 进行Connect和call,拿到Response后进行拆包岂不就可以实现动态的client端?CXF和AXIS/2说到底就是把XML的组装的分拆进行了封装,而恰好是这些封装,导致了很多时候出现Web Service通用性问题。


调出JDK API,直接查找javax.xml.soap包,寥寥几行代码解决了让我头疼一个月的问题:

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import javax.xml.messaging.URLEndpoint;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

import org.apache.log4j.Logger;

/**
 * SOAP底层方式实现与Web Service通讯。
 * 
 * @author Alex Woo
 *
 */
public class DynamicSoapCall {

	private static final Logger log = Logger.getLogger(DynamicSoapCall.class);
	
    private String wsdlURI = null;
    
    public DynamicSoapCall(String wsdlURI) throws Exception {
        log.info("Reading WSDL document from '" + wsdlURI + "'");
        
        this.wsdlURI = wsdlURI;
    }
    
    public SOAPMessage soapCall(String xmlString, String charsetName, String soapVersion) throws Exception {
    	if(null == xmlString) xmlString = ""; 
    	
    	byte[] bytes = null;
    	if(null == charsetName || charsetName.trim().equals("")) {
    		bytes = xmlString.getBytes();
    	} else {
    		try {
    			bytes = xmlString.getBytes(charsetName);
    		} catch(UnsupportedEncodingException e) {
				log.warn("不支持指定的字符集,将按照操作系统默认字符集转换。可能会导致发送数据(特别是中文字符等数据)乱码。");
    			bytes = xmlString.getBytes();
    		}
    	}
    	
    	InputStream is = new ByteArrayInputStream(bytes);
    	
    	return soapCall(is, soapVersion);
    }
    
	public SOAPMessage soapCall(InputStream is, String soapVersion) throws Exception {
		MessageFactory mf = null;
		if(null != soapVersion && soapVersion.trim().equals("1.2")) {
			mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
		} else {//SOAP 1.1 is default.
			mf = MessageFactory.newInstance();
		}
		SOAPMessage message = null;
		
		try {
			message = mf.createMessage(null, is);
		} catch(SOAPException e) {
			throw new Exception("根据Request XML数据创建的SOAP Message消息无效。错误原因:" + e.getCause());
		}

		SOAPConnectionFactory soapFactory = SOAPConnectionFactory.newInstance();  
		SOAPConnection con = soapFactory.createConnection();  

		URLEndpoint endpoint=new URLEndpoint(wsdlURI);  
		SOAPMessage response=con.call(message, endpoint);  
		
		return response;
	}
	
}
?



于是,我需要面对的就只剩下XML的生成与解析了。

有的时候,抛开现成的框架,问题处理起来反而简单啊!

?

1 楼 brooklyng60 2012-04-26  
能详细点吗,这种方式就是想达到的,不用写客户端,cxf,axis无非就是自己封装了一下,怎么调用啊
比如说现在有一个
getMessage方法,接收3个参数,返回1个参数,怎么做啊
  相关解决方案