寫在前面:
呼叫webservice的方式有很多:1.直接在客戶端使用工具產生客戶端程式碼,將程式碼拷貝項目中調用即可;2.使用對應的webservice框架來進行調用,例如如果我們我的服務端開發用的是axis,那麼我在客戶端也可以導入相應的axis的jar包,然後用它相關的方法來進行呼叫;3.js呼叫;4.URLConnection呼叫。上面的前兩種方式個人認為比較適用於服務端與客戶端都是java開發系統,如果是不同語言的呼叫那就不好說了。而第三種與第四種的方式其實差不多,如果在jsp頁面中就要調用接口,就用js這種方式,如果需要在後台寫程序來調用,就比較推薦URLConnection了(現在只是會用,其實它的一些原理什麼的我還是很模糊,比如這種方式應該是http??調用?但是jdk是1.4。故選擇了axis1.4來進行開發(只有這個比較適合專案的環境)。
這裡我也是用的java語言來做測試的,是可以呼叫的。解析服務端回傳的資料需要用到相關jar包:
# 程式碼:
package edu.hue.client;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.StringReader;import java.net.HttpURLConnection;import java.net.ProtocolException;import java.net.URL;import java.net.URLConnection;import java.util.List;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class XMLClient2 {public static void main(String[] args) {try {//创建url地址URL url = new URL("http://10.203.138.82:8080/test_axis3/services/sayHello?wsdl");//打开连接URLConnection conn = url.openConnection();//转换成HttpURLHttpURLConnection httpConn = (HttpURLConnection) conn; System.setProperty("sun.net.client.defaultConnectTimeout", "30000"); System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //打开输入输出的开关httpConn.setDoInput(true); httpConn.setDoOutput(true);//post提交不能有缓存httpConn.setUseCaches(false); //设置请求方式httpConn.setRequestMethod("POST"); //设置请求的头信息httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8"); //设置 SOAPAction Header 不然 报错 没有这个soapaction headerhttpConn.setRequestProperty("SOAPAction", ""); //拼接请求消息 这里的请求消息体 直接用接口测试工具 soapui 来获取 然后拼接以下 注意双引号这里要转义成\" String data = "<soapenv:Envelope xmlns:soapenv=" + "\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:ser=\"http://server.hue.edu/\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"//+"<soapenv:Header />" +"<soapenv:Body>" +"<ser:say soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +"<name xsi:type=\"soapenc:string\" xs:type=\"type:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xs=\"http://www.w3.org/2000/XMLSchema-instance\">" +"小蚊子qq:513996980" //这里是直接在soapui中复制过来的所以它的请求消息体比较长 也可以用下面这种 注释的方式来拼接+"</name>" +"</ser:say>" +"</soapenv:Body>" +"</soapenv:Envelope>"; /* 下面这种请求消息体更为简单 经过测试也可以成功 它的方法名 参数名 都很简洁 * 但是为了保险 希望大家在写请求消息体的时候用 接口测试工具去获取比如soapui 然后直接复制过来 String data = "<soapenv:Envelope xmlns:soapenv=" + "\"\" " + "xmlns:ser=\"http://server.hue.edu/\" " + "xmlns:xsd=\"\" " + "xmlns:xsi=\"\">" +"<soapenv:Header />" +"<soapenv:Body>" +"<ser:say >" +"<name>小蚊子qq:513996980</name>" +"</ser:say>" +"</soapenv:Body>" +"</soapenv:Envelope>";*/ //获得输出流OutputStream out = httpConn.getOutputStream();//发送数据 这里注意要带上编码utf-8 不然 不能传递中文参数过去out.write(data.getBytes("UTF-8"));//判断请求成功if(httpConn.getResponseCode() == 200){ System.out.println("调用成功.....");//获得输入流InputStream in = httpConn.getInputStream();//使用输入流的缓冲区BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8")); StringBuffer sb = new StringBuffer(); String line = null;//读取输入流while((line = reader.readLine()) != null){ sb.append(line); } //创建sax的读取器 这里需要导入相应的jar包SAXReader saxReader = new SAXReader();//创建文档对象Document doc = saxReader.read(new StringReader(sb.toString()));//获得请求响应return元素 这里可根据接口测试工具查看你的相应消息体的返回值的节点是什么名称 我这里是sayReturnList eles = doc.selectNodes("//sayReturn"); for(int i=0;i<eles.size();i++){ Element ele = (Element)eles.get(i); System.out.println(ele.getText()); } System.out.println(sb.toString()); }else{ //调用不成功 打印错误的信息 //获得输入流InputStream err = httpConn.getErrorStream();//使用输入流的缓冲区BufferedReader reader = new BufferedReader(new InputStreamReader(err,"UTF-8")); StringBuffer sb = new StringBuffer(); String line = null;//读取输入流while((line = reader.readLine()) != null){ sb.append(line); } System.out.println("返回错误码:"+httpConn.getResponseCode()); System.out.println("返回的结果:"+sb.toString()); } } catch (Exception e) { e.printStackTrace(); } } }上面是客戶端呼叫的程式碼,服務端這裡就不多貼了,就只是一個方法,裡面有一個String類型的參數。
問題總結:
at sun.net.www.protocolConnection.http.HttpURL.http.HttURL. .java:1626)
這裡的500錯誤一般都是你的程式碼有問題哪裡可能寫的有點不對這個時候就要仔細仔細再仔細然後嘗試用不同的方式去排除錯誤所在的地方也要多百度多查,這裡我出現這個問題是因為把輸入流寫在輸出流的前面(對於客戶端,應該是先寫輸出流之後,再寫輸入流get.InputStream())
2.針對axis1.4的bug:AxisFault faultCode: {}Client.NoSOAPAction faultSubcode: fault: noaultAPActions. SOAPAction header! no SOAPAction header! 這裡可以注意如果報這個錯誤加上一行程式碼就好了啦當初為了這個錯誤幾乎看了一兩天的部落格文章 但是卻沒有人告訴具體的程式碼解決辦法(有兩種解決方法1:在客戶端加上soapaction,其具體內容不重要,寫一個空的字串也是可以的2:服務端重寫寫一個servlet,與axisServlet一樣,並重新改寫裡面的getSoapAction ()方法,這裡推薦只第一種,畢竟這個也不算是axis的bug)
//設定SOAPAction Header 不然報錯沒有這個soapaction headerhttpConn.setRequest("SOAPAction",Property("SOAPAction" "");
3.如果客戶端傳遞參數為中文就報錯:變成位元組數組的時候加上UTF-8
//傳送資料 在這裡注意要帶編碼utf-8 不然無法傳送中文參數過去
out.write(data.getBytes("UTF-8"));##8"));## #### ###### #######問題:############# 如果方法沒有參數需要怎麼呼叫? ? ?在這裡 之前跨平台呼叫wcf開發的.net系統的時候調用的接口方法是不需要傳遞參數的但是也傳了一個空的字符串過去就好了 也沒有寫什麼soap請求消息體什麼的 但是這裡因為是webservice 它是基於soap的所以這裡傳遞資料不管有沒有參數 應該都是要寫上訊息請求體的所以這裡需要注意一下###### 例如:######// 但是为了保险 希望大家在写请求消息体的时候用 接口测试工具去获取比如soapui 然后直接复制过来 String data = "<soapenv:Envelope xmlns:soapenv=" + "\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:ser=\"http://server.hue.edu/\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +"<soapenv:Header />" +"<soapenv:Body>" +"<ser:say >"//比如这里要调用的方法没有参数 就直接不用写就好 但是这个消息体 应该还是要的 +"</ser:say>" +"</soapenv:Body>" +"</soapenv:Envelope>";##### # ###
以上是使用URLConnection和axis1.4開發webservice教程的詳細內容。更多資訊請關注PHP中文網其他相關文章!