工作需要想要实现一个动态调用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个参数,怎么做啊
比如说现在有一个
getMessage方法,接收3个参数,返回1个参数,怎么做啊