用JAX-WS(Java API for XML Web Services)調用WebService不須要引入其餘框架,都是JDK自帶的;文中所使用到的軟件版本:Java 1.8.0_19一、Dom4j 2.1.1。html
參考Java調用WebService方法總結(1)--準備工做java
Dispatch又有Payload方式和Message兩種方式。web
在payload方式中,只需傳入SOAP消息中的body部分。服務器
/** * dispatch Payload方式調用WebService * @param portName 端口名稱 * @param param 參數 */ public static void dispatchPayload(String portName, String param) { try { StringBuffer source = new StringBuffer(); source.append("<web:toTraditionalChinese xmlns:web=\"" + targetNamespace + "\">"); source.append("<web:sText>").append(param).append("</web:sText>"); source.append("</web:toTraditionalChinese>"); StreamSource xmlSource = new StreamSource(new StringReader(source.toString())); URL wsdlURL = new URL(url); QName serviceQName = new QName(targetNamespace, "TraditionalSimplifiedWebService"); Service service = Service.create(wsdlURL, serviceQName); QName portQName = new QName(targetNamespace, portName); Dispatch<Source> dispatch = service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD); //.NET的服務端Soap1.1須要,不加會報錯誤:服務器未能識別 HTTP 頭 SOAPAction 的值 Map<String, Object> requestContext = dispatch.getRequestContext(); requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "http://webxml.com.cn/toTraditionalChinese"); Source orderSource = dispatch.invoke(xmlSource); StreamResult result = new StreamResult(new ByteArrayOutputStream()); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(orderSource, result); ByteArrayOutputStream baos = (ByteArrayOutputStream) result.getOutputStream(); String responseContent = new String(baos.toByteArray()); System.out.println(responseContent); Reader file = new StringReader(responseContent); SAXReader reader = new SAXReader(); Document dc = reader.read(file); Element root = dc.getRootElement(); String r = root.elementText("toTraditionalChineseResult").trim(); System.out.println(r); } catch (Exception e) { e.printStackTrace(); } }
在Message方式中,需傳入整個Soap消息。app
/** * dispatch Payload方式調用WebService * @param soapNamespace soap消息整個消息體的命名空間,Soap1.1和Soap1.2不同 * @param portName 端口名稱 * @param param 參數 */ public static void dispatchMessage(String soapNamespace, String portName, String param) { try { StringBuffer source = new StringBuffer(); source.append("<soapenv:Envelope xmlns:soapenv=\"" + soapNamespace + "\" xmlns:web=\"" + targetNamespace + "\">"); source.append("<soapenv:Header/>"); source.append("<soapenv:Body>"); source.append("<web:toTraditionalChinese>"); source.append("<web:sText>").append(param).append("</web:sText>"); source.append("</web:toTraditionalChinese>"); source.append("</soapenv:Body>"); source.append("</soapenv:Envelope>"); StreamSource xmlSource = new StreamSource(new StringReader(source.toString())); URL wsdlURL = new URL(url); QName serviceQName = new QName(targetNamespace, "TraditionalSimplifiedWebService"); Service service = Service.create(wsdlURL, serviceQName); QName portQName = new QName(targetNamespace, portName); Dispatch<Source> dispatch = service.createDispatch(portQName, Source.class, Service.Mode.MESSAGE); //.NET的服務端Soap1.1須要,不加會報錯誤:服務器未能識別 HTTP 頭 SOAPAction 的值 Map<String, Object> requestContext = dispatch.getRequestContext(); requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "http://webxml.com.cn/toTraditionalChinese"); Source orderSource = dispatch.invoke(xmlSource); StreamResult result = new StreamResult(new ByteArrayOutputStream()); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(orderSource, result); ByteArrayOutputStream baos = (ByteArrayOutputStream) result.getOutputStream(); String responseContent = new String(baos.toByteArray()); System.out.println(responseContent); Reader file = new StringReader(responseContent); SAXReader reader = new SAXReader(); Document dc = reader.read(file); //節點名稱爲toTraditionalChineseResult 命名空間爲http://webxml.com.cn/ String r = dc.selectSingleNode("//*[local-name()='toTraditionalChineseResult' and namespace-uri()='http://webxml.com.cn/']").getText().trim(); System.out.println(r); } catch (Exception e) { e.printStackTrace(); } }
代碼中的設置的信息均可以在準備工做中查詢到,或WSDL中或Soap消息中,這裏就不一一解釋了。完整代碼以下:框架
package com.inspur.ws; import java.io.ByteArrayOutputStream; import java.io.Reader; import java.io.StringReader; import java.net.URL; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.ws.BindingProvider; import javax.xml.ws.Dispatch; import javax.xml.ws.Service; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * JAX-WS Dispatch方式調用WebService樣例 * @author wuyy * */ public class JaxWsDispatch { private static String url = "http://www.webxml.com.cn/WebServices/TraditionalSimplifiedWebService.asmx?wsdl"; private static String targetNamespace = "http://webxml.com.cn/"; /** * dispatch Payload方式調用WebService * @param portName 端口名稱 * @param param 參數 */ public static void dispatchPayload(String portName, String param) { try { StringBuffer source = new StringBuffer(); source.append("<web:toTraditionalChinese xmlns:web=\"" + targetNamespace + "\">"); source.append("<web:sText>").append(param).append("</web:sText>"); source.append("</web:toTraditionalChinese>"); StreamSource xmlSource = new StreamSource(new StringReader(source.toString())); URL wsdlURL = new URL(url); QName serviceQName = new QName(targetNamespace, "TraditionalSimplifiedWebService"); Service service = Service.create(wsdlURL, serviceQName); QName portQName = new QName(targetNamespace, portName); Dispatch<Source> dispatch = service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD); //.NET的服務端Soap1.1須要,不加會報錯誤:服務器未能識別 HTTP 頭 SOAPAction 的值 Map<String, Object> requestContext = dispatch.getRequestContext(); requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "http://webxml.com.cn/toTraditionalChinese"); Source orderSource = dispatch.invoke(xmlSource); StreamResult result = new StreamResult(new ByteArrayOutputStream()); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(orderSource, result); ByteArrayOutputStream baos = (ByteArrayOutputStream) result.getOutputStream(); String responseContent = new String(baos.toByteArray()); System.out.println(responseContent); Reader file = new StringReader(responseContent); SAXReader reader = new SAXReader(); Document dc = reader.read(file); Element root = dc.getRootElement(); String r = root.elementText("toTraditionalChineseResult").trim(); System.out.println(r); } catch (Exception e) { e.printStackTrace(); } } /** * dispatch Payload方式調用WebService * @param soapNamespace soap消息整個消息體的命名空間,Soap1.1和Soap1.2不同 * @param portName 端口名稱 * @param param 參數 */ public static void dispatchMessage(String soapNamespace, String portName, String param) { try { StringBuffer source = new StringBuffer(); source.append("<soapenv:Envelope xmlns:soapenv=\"" + soapNamespace + "\" xmlns:web=\"" + targetNamespace + "\">"); source.append("<soapenv:Header/>"); source.append("<soapenv:Body>"); source.append("<web:toTraditionalChinese>"); source.append("<web:sText>").append(param).append("</web:sText>"); source.append("</web:toTraditionalChinese>"); source.append("</soapenv:Body>"); source.append("</soapenv:Envelope>"); StreamSource xmlSource = new StreamSource(new StringReader(source.toString())); URL wsdlURL = new URL(url); QName serviceQName = new QName(targetNamespace, "TraditionalSimplifiedWebService"); Service service = Service.create(wsdlURL, serviceQName); QName portQName = new QName(targetNamespace, portName); Dispatch<Source> dispatch = service.createDispatch(portQName, Source.class, Service.Mode.MESSAGE); //.NET的服務端Soap1.1須要,不加會報錯誤:服務器未能識別 HTTP 頭 SOAPAction 的值 Map<String, Object> requestContext = dispatch.getRequestContext(); requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE); requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "http://webxml.com.cn/toTraditionalChinese"); Source orderSource = dispatch.invoke(xmlSource); StreamResult result = new StreamResult(new ByteArrayOutputStream()); Transformer trans = TransformerFactory.newInstance().newTransformer(); trans.transform(orderSource, result); ByteArrayOutputStream baos = (ByteArrayOutputStream) result.getOutputStream(); String responseContent = new String(baos.toByteArray()); System.out.println(responseContent); Reader file = new StringReader(responseContent); SAXReader reader = new SAXReader(); Document dc = reader.read(file); //節點名稱爲toTraditionalChineseResult 命名空間爲http://webxml.com.cn/ String r = dc.selectSingleNode("//*[local-name()='toTraditionalChineseResult' and namespace-uri()='http://webxml.com.cn/']").getText().trim(); System.out.println(r); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { //Soap1.1對應的portName爲TraditionalSimplifiedWebServiceSoap,Soap1.2對應的portName爲TraditionalSimplifiedWebServiceSoap12 dispatchPayload("TraditionalSimplifiedWebServiceSoap", "小學"); dispatchPayload("TraditionalSimplifiedWebServiceSoap12", "大學"); //Soap1.1對應的soapNamespace爲http://schemas.xmlsoap.org/soap/envelope/,Soap1.1對應的soapNamespace爲http://www.w3.org/2003/05/soap-envelope dispatchMessage("http://schemas.xmlsoap.org/soap/envelope/", "TraditionalSimplifiedWebServiceSoap", "小學"); dispatchMessage("http://www.w3.org/2003/05/soap-envelope", "TraditionalSimplifiedWebServiceSoap12", "大學"); } }
該方式代碼很簡潔,需把接口類ITestService拷貝到客戶端工程裏。調用本地服務以下:dom
package com.inspur.ws; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.inspur.zsyw.ws.ITestService; /** * JAX-WS Proxy調用 ,需把接口類拷貝到客戶端 * */ public class JaxWsProxy { private static String url = "http://10.40.103.48:9006/zsywservice/TestService?wsdl"; private static String targetNamespace = "http://ws.zsyw.inspur.com/"; public static void proxy(String param) { try { QName qname = new QName(targetNamespace, "TestService"); Service service = Service.create(new URL(url), qname); ITestService testService = service.getPort(ITestService.class); System.out.println(testService.hello(param)); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { proxy("大學"); } }
RPC方式已不被推薦使用了,但JAX-WS依然支持。改方式與Proxy有點類似,也需把接口類ITestService拷貝到客戶端工程裏面;與Proxy方式不一樣的是:接口類還需繼承java.rmi.Remote接口,使用的類是javax.xml.rpc包下。ide
package com.inspur.ws; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; import com.inspur.zsyw.ws.ITestService; /** * JAX-WS RPC調用 ,需把接口類拷貝到客戶端,接口類需繼承java.rmi.Remote接口 * */ public class JaxWsRpc { private static String url = "http://10.40.103.48:9006/zsywservice/TestService?wsdl"; private static String targetNamespace = "http://ws.zsyw.inspur.com/"; public static void rpc(String param) { try { ServiceFactory serviceFactory = ServiceFactory.newInstance(); Service service = serviceFactory.createService(new URL(url), new QName(targetNamespace, "TestService")); ITestService testService = (ITestService) service.getPort(ITestService.class); String result = testService.hello(param); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { rpc("大學"); } }