Java調用WebService方法總結(2)--JAX-WS調用WebService

用JAX-WS(Java API for XML Web Services)調用WebService不須要引入其餘框架,都是JDK自帶的;文中所使用到的軟件版本:Java 1.8.0_19一、Dom4j 2.1.1。html

一、準備

參考Java調用WebService方法總結(1)--準備工做java

二、調用

2.一、Dispatch方式

Dispatch又有Payload方式和Message兩種方式。web

2.1.一、Payload方式

在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();
    }
}

2.1.二、Message方式

在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();
    }
}

2.1.三、完整代碼

代碼中的設置的信息均可以在準備工做中查詢到,或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", "大學");
    }

}
View Code

2.二、Proxy方式

該方式代碼很簡潔,需把接口類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("大學");
    }
}

2.三、RPC方式

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("大學");
    }
}
相關文章
相關標籤/搜索