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


寫在前面:

  調用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>";

 交流群:527038646  嘻嘻嘻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM