通过访问公网服务地址 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)Javajdk1.8.0_91inwsimport.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页面上调用服务的一种方式。