• java使用POST发送soap报文请求webservice返回500错误解析


    本文使用JAX-WS2.2编译webservice,并使用HttpUrlConnection的POST方式对wsdl发送soap报文进行请求返回数据,

    对错误Server returned HTTP response code: 500 的解决方法进行简单分析。

    问题描述:

    由于课程需要博主需要自己写一个webservice并且通过soap进行请求,

    于是使用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进行请求,这边贴一下代码,应该很多人都有查到类似的方法

    HttpUrlConnection请求实现代码:

    [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代码如下:

    [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>  

    这段代码是网上找的,并没有错误,但是一运行就懵逼了,报了下面的错误

    明明直接在浏览器查看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. }  
  • 相关阅读:
    团队作业3-需求分析设计
    团队作业2
    Gakki赛高-团队介绍
    201521123002 《Java程序设计》第2周学习总结
    201521123002 《Java程序设计》第1周学习总结
    201521123067《Java程序设计》第1周学习总结
    团队作业4--第一次项目冲刺(Alpha版本)7
    团队作业4--第一次项目冲刺(Alpha版本)6
    团队作业4--第一次项目冲刺(Alpha版本) 5
    团队作业4--第一次项目冲刺(Alpha版本) 4
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/6815857.html
Copyright © 2020-2023  润新知