1. 程式人生 > >使用URLConnection調用axis1.4開發的webservice

使用URLConnection調用axis1.4開發的webservice

for 方法名 java語言 js調用 .get main 發的 開發 sdl

寫在前面:

  調用webservice的方式有很多:1.直接在客戶端使用工具生成客戶端代碼,將代碼拷進項目中調用即可;2.使用對應的webservice框架來進行調用,比如如果我們我的服務端開發用的是axis,那麽我在客戶端也可以導入相應的axis的jar包,然後用它相關的方法來進行調用;3.js調用;4.URLConnection調用。上面的前兩種方式個人認為比較適用於服務端與客戶端都是java開發系統,如果是不同語言的調用那就不好說了。而第三種與第四種的方式其實差不多,如果在jsp頁面中就要調用接口,就用js這種方式,如果需要在後臺寫程序來調用,就比較推薦URLConnection了(現在只是會用,其實它的一些原理什麽的我還是很模糊,比如這種方式應該是http??調用??,還不是很清楚呢)

  最近項目要開發webservice接口,但是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(); //轉換成HttpURL HttpURLConnection 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 header httpConn.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=" + "\"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 >" +"<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元素 這裏可根據接口測試工具查看你的相應消息體的返回值的節點是什麽名稱 我這裏是sayReturn List 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類型的參數。

  問題總結:

  1.報錯誤 說http response result code 500:

  java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.203.138.82:8080/test_axis/services/sayHello
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626)

  這裏的500錯誤 一般都是你的代碼有問題 哪裏可能寫的有點不對 這個時候就要仔細仔細再仔細 然後嘗試用不同的方式去排除錯誤所在的地方 也要多百度 多查 ,這裏我出現這個問題 是因為把輸入流寫在輸出流的前面(對於客戶端,應該是先寫輸出流之後,再寫輸入流get.InputStream())

  2.針對axis1.4的bug:AxisFault faultCode: {http://xml.apache.org/axis/}Client.NoSOAPAction faultSubcode:      faultString: no SOAPAction header! faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}stackTrace:no                 SOAPAction header!

no SOAPAction header! 這裏可以註意 如果報這個錯 加上一行代碼就好了啦 當初為了這個錯誤 幾乎看了一兩天的博客文章 但是卻沒有人告訴具體的代碼解決辦法(有兩種解決辦法1:在客戶端加上soapaction,其具體內容不重要,寫一個空的字符串也是可以的 2:服務端重寫寫一個servlet,與axisServlet一樣,並重新改寫裏面的getSoapAction()方法,這裏推薦只第一種,畢竟這個也算不上是axis的bug)

  //設置 SOAPAction Header 不然 報錯 沒有這個soapaction header
  httpConn.setRequestProperty("SOAPAction", "");

  3.如果客戶端傳遞參數為中文就報錯:變為字節數組的時候加上UTF-8

  //獲得輸出流
 OutputStream out = httpConn.getOutputStream();
//發送數據 這裏註意要帶上編碼utf-8 不然 不能傳遞中文參數過去
out.write(data.getBytes("UTF-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