java使用POST發送soap報文請求webservice返回500錯誤解析

本文使用JAX-WS2.2編譯webservice,並使用HttpUrlConnection的POST方式對wsdl發送soap報文進行請求返回數據,html

對錯誤Server returned HTTP response code: 500 的解決方法進行簡單分析。java

 

問題描述:

因爲課程須要博主須要本身寫一個webservice而且經過soap進行請求,web

因而使用JAX-WS編譯了下面java代碼生成webservice服務數組

 

生成webservice的java代碼:瀏覽器

 

[java]  view plain  copy
 
  1. @WebService()  
  2. public class HelloWorld {  
  3.   @WebMethod  
  4.   public String sayHelloWorldFrom(String from) {  
  5.       System.out.println("getMessage.");  
  6.       String result = "Hello, world, from " + from;  
  7.       System.out.println(result);  
  8.       return result;  
  9.   }  
  10.   public static void main(String[] argv) {  
  11.     System.out.println("Service is running...");  
  12.   
  13.     Object implementor = new HelloWorld ();  
  14.     String address = "http://localhost:9000/HelloWorld";  
  15.     Endpoint.publish(address, implementor);  
  16.   }  
  17. }  

查看webservice服務器

 

 

在網上查到的一個方法就是經過HttpUrlConnection進行請求,這邊貼一下代碼,應該不少人都有查到相似的方法app

HttpUrlConnection請求實現代碼:url

 

[java]  view plain  copy
 
  1. public static void main(String[] args) throws Exception  
  2.     {  
  3.         String urlString = "http://localhost:9000/HelloWorld?wsdl";//自定義的wsdl服務  
  4.         URL url = new URL(urlString);  
  5.         HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();//打開鏈接  
  6.   
  7.         String xmlFile = "soap_xml\\soap.xml";//要發送的soap格式文件  
  8.         File fileToSend = new File(xmlFile);  
  9.         byte[] buf = new byte[(int) fileToSend.length()];// 用於存放文件數據的數組  
  10.   
  11.         new FileInputStream(xmlFile).read(buf);  
  12.   
  13.         //Content-Length長度會自動進行計算  
  14.         httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");  
  15.         httpConn.setRequestMethod("POST");  
  16.         httpConn.setDoOutput(true);  
  17.         httpConn.setDoInput(true);  
  18.   
  19.         OutputStream out = httpConn.getOutputStream();  
  20.   
  21.         out.write(buf);  
  22.         out.close();  
  23.   
  24.         InputStreamReader is = new InputStreamReader(httpConn.getInputStream());  
  25.         BufferedReader in = new BufferedReader(is);  
  26.         String inputLine;  
  27.         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
  28.                 new FileOutputStream("result.xml")));// 將結果存放的位置  
  29.         while ((inputLine = in.readLine()) != null)  
  30.         {  
  31.             System.out.println(inputLine);  
  32.             bw.write(inputLine);  
  33.             bw.newLine();  
  34.         }  
  35.         bw.close();  
  36.         in.close();  
  37.         httpConn.disconnect();  
  38.     }  

soap.xml代碼以下:spa

 

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  3.     <soap:Body>  
  4.         <sayHelloWorldFrom>  
  5.             <arg0>  
  6.                 撐撐  
  7.             </arg0>  
  8.         </sayHelloWorldFrom>  
  9.     </soap:Body>  
  10. </soap:Envelope>  

 

這段代碼是網上找的,並無錯誤,可是一運行就懵逼了,報了下面的錯誤.net

明明直接在瀏覽器查看wsdl接口是能夠訪問頁面,可是返回500錯誤

錯誤代碼:

 

[java]  view plain  copy
 
  1. Exception in thread "main" java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:9000/HelloWorld?wsdl  
  2.     at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1839)  
  3.     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)  
  4.     at soap.HelloSoap.main(HelloSoap.java:38)  
  5.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  6.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
  7.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  8.     at java.lang.reflect.Method.invoke(Method.java:497)  
  9.     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)  

錯誤語句指向

 

[java]  view plain  copy
 
  1. InputStreamReader is = new InputStreamReader(httpConn.getInputStream());  

 

 

而網上其餘大部分文章都沒有給解決方法,或者給了其餘的解決方法,我就在這邊分享一下這個問題的詳細解決方法。

 

解決流程(乾貨

首先應該確認具體的錯誤,經過下面的語句能夠了解InputStream的錯誤詳情。

 

[java]  view plain  copy
 
  1. InputStream is = httpConn.getErrorStream();    //經過getErrorStream瞭解錯誤的詳情,由於錯誤詳情也以XML格式返回,所以也能夠用JDOM來獲取。  

 

 

這個語句其實也是從請求的服務方取回的錯誤信息,實質也是xml內容,用上面的BufferReader那一連串的語句解析出具體內容,而後輸出查看,具體代碼以下:  

 

[java]  view plain  copy
 
  1. InputStream is = httpConn.getErrorStream();    //經過getErrorStream瞭解錯誤的詳情,由於錯誤詳情也以XML格式返回,所以也能夠用JDOM來獲取。  
  2. InputStreamReader isr = new InputStreamReader(is,"utf-8");  
  3. BufferedReader in = new BufferedReader(isr);  
  4. String inputLine;  
  5. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
  6.         new FileOutputStream("result.xml")));// 將結果存放的位置  
  7. while ((inputLine = in.readLine()) != null)   
  8. {  
  9.     System.out.println(inputLine);  
  10.     bw.write(inputLine);  
  11.     bw.newLine();  
  12.     bw.close();  
  13. }  
  14. in.close();  

錯誤詳情輸出以下:

 

 

[html]  view plain  copy
 
  1. <?xml version='1.0' encoding='UTF-8'?>  
  2. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">  
  3.     <S:Body>  
  4.         <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">  
  5.             <faultcode>  
  6.                 S:Client  
  7.             </faultcode>  
  8.             <faultstring>  
  9.                 找不到{}sayHelloWorldFrom的分派方法  
  10.             </faultstring>  
  11.         </S:Fault>  
  12.     </S:Body>  
  13. </S:Envelope>  


在這邊就要注意了!這個xml文件是第一個要點!

 

分析一下這段xml代碼,能夠看到有一個faultcode和faultstring,這就是解決這個問題的第一個突破口

 

靈光一閃百度了一下SOAP Fault(百科鏈接:http://baike.baidu.com/link?url=vehb23KNtl58uv2cwVDk8LYzDTUC4MHW9kmpaALl9qht9VXp8ASufe0QlpUrEELEApdKx80AMPzMsfCbUJtWiK

 

這樣就一目瞭然了,錯誤代碼中faultcode所含的是Client,說明傳遞的消息有誤,服務端是沒有問題的。

因而從要發送的soap中查找錯誤。

這時候發現faultstring 「{}找不到xxx的分派方法」 中有一個大括號,想不明白那個是什麼,恰好查看了一下web服務的頁面,就是最上面那張圖片,發現服務名和端口名那邊也有大括號{http://example/},而後也想起來以前看的其餘xml代碼中,要發送的方法的那個節點中有寫命名空間(xmlns),就是網上那個getWeatherByCityName的那個例子,你們應該都有看過,我就再也不這邊費口舌了。

要是有仔細看我發送的soap.xml的代碼,就能夠看到sayHelloWorldFrom那個節點沒有寫命名空間,實在是查了這麼多代碼網上都沒人提到,也沒有查到關於soap報文的編寫規範,還覺得那邊能夠不用寫,因而刪掉了。

問題就出在這,我從新試了一下,先把命名空間隨便寫了個網址,再次運行後依然報錯,可是大括號中就有了命名空間指向的網址了,因而把web服務裏的大括號裏的地址,即{http://example/}寫上去,總算是請求成功併成功返回數據!

 

修改後的soap.xml(就是添加了命名空間)

 

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  3.     <soap:Body>  
  4.         <m:sayHelloWorldFrom xmlns:m="http://example/">  
  5.             <arg0>  
  6.                 撐撐  
  7.             </arg0>  
  8.         </m:sayHelloWorldFrom>  
  9.     </soap:Body>  
  10. </soap:Envelope>  


大括號裏的地址其實就是wsdl中denfinition裏定義的targetNameSpace,具體解釋我貼個連接吧你們本身看吧,反正知道問題出在這邊總算是解決了。

 

WebService 之 WSDL文件 講解 http://blog.itpub.net/20200170/viewspace-740276/

 

其實出了bug第一反應確實應該是找Error信息,這樣纔好針對性的進行處理,若是本文的方法還沒辦法幫你解決的話,那仍是建議你們靠前面查看錯誤詳情的方法去進行bug的查找~

主要內容到這邊結束啦,但願能幫到你們~

 

附錄

發送httpUrlConnection的java代碼
[java]  view plain  copy
 
  1. package soap;  
  2.   
  3. import java.io.*;  
  4. import java.net.HttpURLConnection;  
  5. import java.net.URL;  
  6.   
  7. /** 
  8.  * Created by cc on 2016/10/21. 
  9.  */  
  10. public class HelloSoap {  
  11.   
  12.     public static void main(String[] args) throws Exception  
  13.     {  
  14.         String urlString = "http://localhost:9000/HelloWorld?wsdl";//wsdl文檔的地址  
  15.         URL url = new URL(urlString);  
  16.         HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();//打開鏈接  
  17.   
  18.         //String soapActionString = "http://localhost:9000/HelloWorld/sayHelloWorldFrom";//Soap 1.1中使用  
  19.   
  20.         String xmlFile = "soap_xml\\soap.xml";//要發送的soap格式文件  
  21.         File fileToSend = new File(xmlFile);  
  22.         byte[] buf = new byte[(int) fileToSend.length()];// 用於存放文件數據的數組  
  23.   
  24.         new FileInputStream(xmlFile).read(buf);  
  25.   
  26.         //Content-Length長度會自動進行計算  
  27.         httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");  
  28.         //httpConn.setRequestProperty("soapActionString",soapActionString);//Soap1.1使用 其實徹底能夠不須要  
  29.         httpConn.setRequestMethod("POST");  
  30.         httpConn.setDoOutput(true);  
  31.         httpConn.setDoInput(true);  
  32.   
  33.         OutputStream out = httpConn.getOutputStream();  
  34.   
  35.         out.write(buf);  
  36.         out.close();  
  37.   
  38.         if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)  
  39.         {  
  40.             InputStreamReader is = new InputStreamReader(httpConn.getInputStream());  
  41.             BufferedReader in = new BufferedReader(is);  
  42.             String inputLine;  
  43.             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
  44.                     new FileOutputStream("result.xml")));// 將結果存放的位置  
  45.             while ((inputLine = in.readLine()) != null)  
  46.             {  
  47.                 System.out.println(inputLine);  
  48.                 bw.write(inputLine);  
  49.                 bw.newLine();  
  50.             }  
  51.             bw.close();  
  52.             in.close();  
  53.         }  
  54.         else{  
  55.             //若是服務器返回的HTTP狀態不是HTTP_OK,則表示發生了錯誤,此時能夠經過以下方法瞭解錯誤緣由。  
  56.             InputStream is = httpConn.getErrorStream();    //經過getErrorStream瞭解錯誤的詳情,由於錯誤詳情也以XML格式返回,所以也能夠用JDOM來獲取。  
  57.             InputStreamReader isr = new InputStreamReader(is,"utf-8");  
  58.             BufferedReader in = new BufferedReader(isr);  
  59.             String inputLine;  
  60.             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
  61.                     new FileOutputStream("result.xml")));// 將結果存放的位置  
  62.             while ((inputLine = in.readLine()) != null)  
  63.             {  
  64.                 System.out.println(inputLine);  
  65.                 bw.write(inputLine);  
  66.                 bw.newLine();  
  67.                 bw.close();  
  68.             }  
  69.             in.close();  
  70.   
  71.         }  
  72.         httpConn.disconnect();  
  73.     }  
  74. }  
相關文章
相關標籤/搜索