Web Service基础——四种客户端调用方式

通过访问公网服务地址 http://www.webxml.com.cn/zh_cn/index.aspx 来演示四种不同的客户端调用方式

1. 生成客户端调用方式

1.1 Wsimport命令介绍

首先对之前demo中用到的生成客户端代码的Wsimport命令进行简要介绍——

Wsimport就是jdk提供的的一个工具,他的作用就是根据WSDL地址生成客户端代码;Wsimport的位置在JAVA_HOME/bin,例如我本机的路径D:\Program Files (x86)\Java\jdk1.8.0_91\bin\wsimport.exe 。

Wsimport常用的参数:

  •  -s:生成java文件的
  • -d:生成class文件的,默认的参数
  • -p:指定包名的,如果不加该参数,默认包名就是wsdl文档中的命名空间的倒序 

需要注意的是: Wsimport仅支持SOAP1.1客户端的生成。

1. 2 调用公网手机号归属地查询服务

1.2.1 wsimport生成客户端代码

wsimport -p com.zang.mobile -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL

由于说明书中存在SOAP1.2的实现,所以会报【warning】,并不影响我们接下来的操作

1.2.2 阅读使用说明书,使用生成客户端代码调用服务端

import com.zang.mobile.MobileCodeWS;
import com.zang.mobile.MobileCodeWSSoap;

public class MobileClient {

    public static void main(String[] args) {
        //创建服务视图
        MobileCodeWS mobileCodeWS = new MobileCodeWS();
        //获取服务实现类
        MobileCodeWSSoap mobileCodeWSSoap = mobileCodeWS.getPort(MobileCodeWSSoap.class);
        //调用查询方法
        String result = mobileCodeWSSoap.getMobileCodeInfo("15966688888", null);
        System.out.println(result);
    }
}

1.3 公网天气服务端查询

wsimport -p com.zang.weather -s . http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL

执行上面命令报错

解决方法:网页上将说明书右键-》另存为文件到本地,编辑该文件,删掉 <s:element ref="s:schema" />   (三处),保存。之后通过如下命令本地引用

wsimport -p com.zang.weather -s . file:///C:/Users/Administrator/Desktop/WeatherWS.xml

客户端代码如下

import java.util.List;
import com.zang.weather.ArrayOfString;
import com.zang.weather.WeatherWS;
import com.zang.weather.WeatherWSSoap;

public class WeatherClient {
    public static void main(String[] args) {
        WeatherWS weatherWS = new WeatherWS();
        WeatherWSSoap weatherWSSoap = weatherWS.getPort(WeatherWSSoap.class);
        ArrayOfString arrayOfString = weatherWSSoap.getWeather("济南", "");
        List<String> list = arrayOfString.getString();

        for (String str : list) {
            System.out.println(str);
        }
    }
}

1.4 特点

该种方式使用简单,但一些关键的元素在代码生成时写死到生成代码中,不方便维护,所以仅用于测试。

2. service编程调用方式

 2.1 客户端代码

import java.io.IOException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.zang.mobile.MobileCodeWSSoap;

public class ServiceClient {
    public static void main(String[] args) throws IOException {
        // 创建WSDL的URL,注意不是服务地址
        URL url = new URL(
                "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL");

        // 创建服务名称
        // 1.namespaceURI - 命名空间地址    <s:schema elementFormDefault="qualified" targetNamespace="http://WebXml.com.cn/">
        // 2.localPart - 服务视图名   <wsdl:service name="MobileCodeWS">
        QName qname = new QName("http://WebXml.com.cn/", "MobileCodeWS");

        // 创建服务视图
        // 参数解释:
        // 1.wsdlDocumentLocation - wsdl地址
        // 2.serviceName - 服务名称
        Service service = Service.create(url, qname);
        // 获取服务实现类
        MobileCodeWSSoap mobileCodeWSSoap = service
                .getPort(MobileCodeWSSoap.class);
        // 调用查询方法
        String result = mobileCodeWSSoap.getMobileCodeInfo("15966688888", "");
        System.out.println(result);
    }
}

2.2 特点

该种方式可以自定义关键元素,方便以后维护,是一种标准的开发方式。

3. HttpURLConnection调用方式

3.1 开发步骤

第一步:创建服务地址

第二步:打开一个通向服务地址的连接

第三步:设置参数

设置POST,POST必须大写,如果不大写,报如下异常

如果不设置输入输出,会报如下异常

第四步:组织SOAP数据,发送请求

第五步:接收服务端响应,打印

3.2 客户端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpClient {
    public static void main(String[] args) throws IOException {
        // 第一步:创建服务地址,不是WSDL地址
        URL url = new URL(
                "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
        // 第二步:打开一个通向服务地址的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 第三步:设置参数
        // 3.1发送方式设置:POST必须大写
        connection.setRequestMethod("POST");
        // 3.2设置数据格式:content-type
        connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
        // 3.3设置输入输出,因为默认新创建的connection没有读写权限,
        connection.setDoInput(true);
        connection.setDoOutput(true);

        // 第四步:组织SOAP数据,发送请求
        String soapXML = getXML("15966688888");
        OutputStream os = connection.getOutputStream();
        os.write(soapXML.getBytes());
        // 第五步:接收服务端响应,打印
        int responseCode = connection.getResponseCode();
        if (200 == responseCode) {// 表示服务端响应成功
            InputStream is = connection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            StringBuilder sb = new StringBuilder();
            String temp = null;
            while (null != (temp = br.readLine())) {
                sb.append(temp);
            }
            System.out.println(sb.toString());

            is.close();
            isr.close();
            br.close();
        }

        os.close();
    }

    /**
     * <?xml version="1.0" encoding="utf-8"?> <soap:Envelope
     * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     * xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     * xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body>
     * <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
     * <mobileCode>string</mobileCode> <userID>string</userID>
     * </getMobileCodeInfo> </soap:Body> </soap:Envelope>
     * 
     * @param phoneNum
     * @return
     */
    public static String getXML(String phoneNum) {
        String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                + "<soap:Body>"
                + "<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
                + "<mobileCode>" + phoneNum + "</mobileCode>"
                + "<userID></userID>" + "</getMobileCodeInfo>" + "</soap:Body>"
                + "</soap:Envelope>";
        return soapXML;
    }
}

3.3 特点

步骤较繁琐,用来模拟客户端,演示客户端实现原理。

4. Ajax调用方式

4.1 实现代码

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript">
    function queryMobile(){
        //创建XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        //打开连接
        xhr.open("post","http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx",true);
        //设置数据类型
        xhr.setRequestHeader("content-type","text/xml;charset=utf-8");
        //设置回调函数
        xhr.onreadystatechange=function(){
            //判断是否发送成功和判断服务端是否响应成功
            if(4 == xhr.readyState && 200 == xhr.status){
                alert(xhr.responseText);
            }
        }
        //组织SOAP协议数据
        var soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
        +"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
            +"<soap:Body>"
            +"<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
                +"<mobileCode>"+document.getElementById("phoneNum").value+"</mobileCode>"
              +"<userID></userID>"
            +"</getMobileCodeInfo>"
          +"</soap:Body>"
        +"</soap:Envelope>";
        alert(soapXML);
        //发送数据
        xhr.send(soapXML);
    }
  </script>
 </head>
 <body>
  手机号查询:<input type="text" id="phoneNum"/> <input type="button" value="查询" onclick="javascript:queryMobile();"/>
 </body>
</html>

点击之后如果无响应,可能是浏览器防跨域机制导致,参考我的这篇博客

4.2 特点

HTML页面上调用服务的一种方式。

 

posted @ 2018-05-09 00:46  雪山上的蒲公英  阅读(946)  评论(0编辑  收藏  举报
/* 返回顶部代码 */