• Java调用WebService方法总结(2)--JAX-WS调用WebService


    用JAX-WS(Java API for XML Web Services)调用WebService不需要引入其他框架,都是JDK自带的;文中所使用到的软件版本:Java 1.8.0_191、Dom4j 2.1.1。

    1、准备

    参考Java调用WebService方法总结(1)--准备工作

    2、调用

    2.1、Dispatch方式

    Dispatch又有Payload方式和Message两种方式。

    2.1.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.2、Message方式

    在Message方式中,需传入整个Soap消息。

    /**
     * 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.3、完整代码

    代码中的设置的信息都可以在准备工作中查询到,或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.2、Proxy方式

    该方式代码很简洁,需把接口类ITestService拷贝到客户端工程里。调用本地服务如下:

    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.3、RPC方式

    RPC方式已不被推荐使用了,但JAX-WS依然支持。改方式与Proxy有点相似,也需把接口类ITestService拷贝到客户端工程里面;与Proxy方式不同的是:接口类还需继承java.rmi.Remote接口,使用的类是javax.xml.rpc包下

    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("大学");
        }
    }
  • 相关阅读:
    循环队列
    UVa10000_Longest Paths(最短路SPFA)
    最新jhost免费jsp云空间会员邀请码
    Vertica: 基于DBMS架构的列存储数据仓库
    java中接口的定义与实现
    【C++知识汇总】运营商 &amp; 运算符重载
    SVN与eclipse整合和利用、SVN与Apache综合
    Java单链逆转
    hdu1115(重力算法的多边形中心)
    高效C++规划
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/11850797.html
Copyright © 2020-2023  润新知