Java發布webservice應用並發送SOAP請求調用


webservice框架有很多,比如axis、axis2、cxf、xFire等等,做服務端和做客戶端都可行,個人感覺使用這些框架的好處是減少了對於接口信息的解析,最主要的是減少了對於傳遞於網絡中XML的解析,代價是你不得不在你的框架中添加對於這些框架的依賴。個人觀點是:服務端使用這些框架還行,如果做客戶端,沒必要使用這些框架,只需使用httpclient即可。

一、創建並發布一個簡單的webservice應用

  1、webservice 代碼:

 import javax.jws.WebMethod;
 import javax.jws.WebService;
 import javax.xml.ws.Endpoint;
 
 
  @WebService
  public class HelloWorld {
     @WebMethod
     public String sayHello(String str){
         System.out.println("get Message...");
         String result = "Hello World, "+str;
         return result;
     }
     public static void main(String[] args) {
         System.out.println("server is running");
         String address="http://localhost:9000/HelloWorld";
         Object implementor =new HelloWorld();
         Endpoint.publish(address, implementor);
     }
 
 }

  2、運行項目,並訪問 "http://localhost:9000/HelloWorld?wsdl",得到wsdl文件,說明webservice發布成功

  例如天氣的wsdl:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl 

二、客戶端訪問webservice

  1、通過 HttpClient 及  HttpURLConnection 發送SOAP請求,代碼如下: 

  import java.io.BufferedReader;                                                                             
  import java.io.DataOutputStream;                                                                           
  import java.io.InputStream;                                                                                
  import java.io.InputStreamReader;                                                                          
  import java.net.HttpURLConnection;                                                                         
  import java.net.URL;                                                                                       
                                                                                                             
  import org.apache.commons.httpclient.HttpClient;                                                           
  import org.apache.commons.httpclient.methods.PostMethod;                                                   
  import org.apache.commons.httpclient.methods.RequestEntity;                                                
  import org.apache.commons.httpclient.methods.StringRequestEntity;                                          
  import org.apache.commons.io.IOUtils;                                                                      
                                                                                                             
  public class TestHelloWrold {                                                                              
      public static void main(String[] args) throws Exception {                                              
          String wsdl = "http://localhost:9000/HelloWorld?wsdl";                                             
          int timeout = 10000;                                                                               
          StringBuffer sb = new StringBuffer("");                                                            
          sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");                                           
          sb.append("<soap:Envelope "                                                                        
                  + "xmlns:api='http://demo.ls.com/' "                                                       
                  + "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/'>");                              
          sb.append("<soap:Body>");                                                                          
          sb.append("<api:sayHello>");                                                                       
          sb.append("<arg0>ls</arg0>");                                                                      
          sb.append("</api:sayHello>");                                                                      
          sb.append("</soap:Body>");                                                                         
          sb.append("</soap:Envelope>");                                                                     
                                                                                                                                                                                                                       
          // HttpClient發送SOAP請求                                                                              
          System.out.println("HttpClient 發送SOAP請求");                                                         
          HttpClient client = new HttpClient();                                                              
          PostMethod postMethod = new PostMethod(wsdl);                                                      
          // 設置連接超時                                                                                          
          client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);                       
          // 設置讀取時間超時                                                                                        
          client.getHttpConnectionManager().getParams().setSoTimeout(timeout);                               
          // 然后把Soap請求數據添加到PostMethod中                                                                       
          RequestEntity requestEntity = new StringRequestEntity(sb.toString(), "text/xml", "UTF-8");         
          //設置請求頭部,否則可能會報 “no SOAPAction header” 的錯誤                                                         
          postMethod.setRequestHeader("SOAPAction","");                                                      
          // 設置請求體                                                                                           
          postMethod.setRequestEntity(requestEntity);                                                        
          int status = client.executeMethod(postMethod);                                                     
          // 打印請求狀態碼                                                                                         
          System.out.println("status:" + status);                                                            
          // 獲取響應體輸入流                                                                                        
          InputStream is = postMethod.getResponseBodyAsStream();                                             
          // 獲取請求結果字符串                                                                                       
          String result = IOUtils.toString(is);                                                              
          System.out.println("result: " + result);                                                           
                                                                                                                                                                                                                        
          // HttpURLConnection 發送SOAP請求                                                                      
          System.out.println("HttpURLConnection 發送SOAP請求");                                                  
          URL url = new URL(wsdl);                                                                           
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();                                 
                                                                                                             
          conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");                                
          conn.setRequestMethod("POST");                                                                     
          conn.setUseCaches(false);                                                                          
          conn.setDoInput(true);                                                                             
          conn.setDoOutput(true);                                                                            
          conn.setConnectTimeout(timeout);                                                                   
          conn.setReadTimeout(timeout);                                                                      
                                                                                                             
          DataOutputStream dos = new DataOutputStream(conn.getOutputStream());                               
          dos.write(sb.toString().getBytes("utf-8"));                                                        
          dos.flush();                                                                                       
                                                                                                                                                                                                                         
          BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); 
          String line = null;                                                                                
          StringBuffer strBuf = new StringBuffer();                                                          
          while ((line = reader.readLine()) != null) {                                                       
              strBuf.append(line);                                                                           
          }                                                                                                  
          dos.close();                                                                                       
          reader.close();                                                                                    
                                                                                                             
          System.out.println(strBuf.toString());                                                             
      }                                                                                                                                                                                                                   
  }                                                                                                          

  響應報文如下:

<?xml version="1.0" ?>
  <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
      <ns2:sayHelloResponse xmlns:ns2="http://demo.ls.com/">
        <return>Hello World, ls</return>
      </ns2:sayHelloResponse>
    </S:Body>
  </S:Envelope>

SOAP的請求報文的格式是怎么來的呢?

 (1)可用Eclipse測試WSDL文件,則可得到想要的SOAP請求及響應報文,具體步驟如下圖:

   第一步:

    

  第二步:

   通過第一步,會在瀏覽器打開如下的頁面

  

 (2)saopui工具拿到soap報文

  soapUI是一個開源測試工具,通過soap/http來檢查、調用、實現Web Service的功能/負載/符合性測試。該工具既可作為一個單獨的測試軟件使用,也可利用插件集成到Eclipse,maven2.X,Netbeans 和intellij中使用。soapUI pro是soapUI的商業非開源版本,實現的 功能較開源的soapUI更多。

  a、首先得安裝soapUI 4.5.2,安裝后打開,截圖如下:

     

  b、右鍵點擊“Projects”創建工程,截圖如下:

    

  c、雙擊展開左側創建的工程下所有節點,最后雙擊“Request 1”節點,在右側即可拿到soap格式消息,這個就是我們后面作為客戶端調用服務端的報文內容,截圖如下:

    

 

 2、生成客戶端代碼訪問

   a、通過 "wsimport"(JDK自帶)命令生成客戶端代碼。進入命令行模式,執行 wsimport -s . http://localhost:9000/HelloWorld?wsdl,就會在當前目錄下生成客戶端代碼。附圖:

     

     b、通過Eclipse生成客戶端代碼

    

    

  (1).生成本地代碼后可以直接調用,比如調用天氣webservice接口: 

package hanwl.TestDemo;

import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;

import cn.com.WebXml.WeatherWebService;
import cn.com.WebXml.WeatherWebServiceLocator;
import cn.com.WebXml.WeatherWebServiceSoap;

public class TestWebservice {
    public static void main(String[] args) {
        WeatherWebService weatherWebService = new WeatherWebServiceLocator();
        WeatherWebServiceSoap  weatherWebServiceSoap = null;
        try {
            weatherWebServiceSoap = weatherWebService.getWeatherWebServiceSoap();
        } catch (ServiceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        String[] cityweather = null;
        //String[] city={"北京","上海","深圳","廣州"};
         try {
             cityweather = weatherWebServiceSoap.getWeatherbyCityName("北京");//不輸入默認為上海市
         } catch (RemoteException e) {
             e.printStackTrace(); 
        }
         
         for(String s :cityweather){
             System.out.println(s);
             System.out.println("------------------------");
         }
    }

}

  (2).httpclient作為客戶端調用天氣webservice

package hanwl.TestDemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.xml.sax.InputSource;

public class TestWebservice2 {

    public static void main(String[] args) throws IOException {
        
        // TODO Auto-generated method stub
        String wsdl = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";
        int timeout = 1000;
        StringBuffer sb = new StringBuffer("");          
            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
              sb.append("<soapenv:Envelope "                       
                      + "    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
                      + " xmlns:q0='http://WebXml.com.cn/' "
                      + "    xmlns:xsd='http://www.w3.org/2001/XMLSchema' " 
                      + " xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' >");
              sb.append("<soapenv:Body>");
            sb.append("<q0:getWeatherbyCityName>");
            sb.append("<q0:theCityName>唐山</q0:theCityName> ");
            sb.append("</q0:getWeatherbyCityName>");
            sb.append("</soapenv:Body>");
            sb.append("</soapenv:Envelope>");
         
            // HttpClient發送SOAP請求
             System.out.println("HttpClient 發送SOAP請求");
             HttpClient client = new HttpClient();
             PostMethod postMethod = new PostMethod(wsdl);
             // 設置連接超時
             client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
             // 設置讀取時間超時
             client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
             // 然后把Soap請求數據添加到PostMethod中
             RequestEntity requestEntity = new StringRequestEntity(sb.toString(), "text/xml", "UTF-8");
             //設置請求頭部,否則可能會報 “no SOAPAction header” 的錯誤
             //postMethod.setRequestHeader("SOAPAction","");
             // 設置請求體
             postMethod.setRequestEntity(requestEntity);
             int status = client.executeMethod(postMethod);
             // 打印請求狀態碼
             System.out.println("status:" + status);
             // 獲取響應體輸入流
             InputStream is = postMethod.getResponseBodyAsStream();
             // 獲取請求結果字符串
             String result = IOUtils.toString(is);
             Document dc = strXmlToDocument(result);
//             Element root = dc.getRootElement();
//             System.out.println(root.getName());
//             System.out.println("result: " + result);
        
    }
    
    public static Document strXmlToDocument(String parseStrXml){        
         Document document = null;
        try {
            document = DocumentHelper.parseText(parseStrXml);            
            Element root = document.getRootElement();
            List<Element> list = root.elements();
            getElement(list);
        } catch (DocumentException e) {
            e.printStackTrace();
        }          
        return document;
    }
    
    private static void getElement(List<Element> sonElemetList) {
//        Map<String,String> map = new HashMap<String, String>();
        for (Element sonElement : sonElemetList) {
                if (sonElement.elements().size() != 0) {
                    System.out.println(sonElement.getName() + ":");
                    getElement(sonElement.elements());
                }else{
                    System.out.println(sonElement.getName() + ":"+ sonElement.getText());
                }
 
        }
    }    
}

三、總結

       優點:

       1.使用httpclient作為客戶端調用webservice,不用關注繁瑣的webservice框架,只需找到SOAP消息格式,添加httpclient依賴就行。

       2.使用httpclient調用webservice,建議采用soap1.1方式調用,經測試使用soap1.1方式能調用soap1.1和soap1.2的服務端。 

       缺點:

       唯一的缺點是,你得自己解析返回的XML,找到你關注的信息內容。

參考地址:https://blog.csdn.net/zilong_zilong/article/details/53932667

     https://blog.csdn.net/gzxdale/article/details/74242359

 


免責聲明!

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



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