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

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

问题描述:

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

于是使用JAX-WS编译了下面java代码生成webservice服务

生成webservice的java代码:

  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. Object implementor = new HelloWorld ();
  13. String address = "http://localhost:9000/HelloWorld";
  14. Endpoint.publish(address, implementor);
  15. }
  16. }

查看webservice

在网上查到的一个方法就是通过HttpUrlConnection进行请求,这边贴一下代码,应该很多人都有查到类似的方法

HttpUrlConnection请求实现代码:

  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. String xmlFile = "soap_xml\\soap.xml";//要发送的soap格式文件
  7. File fileToSend = new File(xmlFile);
  8. byte[] buf = new byte[(int) fileToSend.length()];// 用于存放文件数据的数组
  9. new FileInputStream(xmlFile).read(buf);
  10. //Content-Length长度会自动进行计算
  11. httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
  12. httpConn.setRequestMethod("POST");
  13. httpConn.setDoOutput(true);
  14. httpConn.setDoInput(true);
  15. OutputStream out = httpConn.getOutputStream();
  16. out.write(buf);
  17. out.close();
  18. InputStreamReader is = new InputStreamReader(httpConn.getInputStream());
  19. BufferedReader in = new BufferedReader(is);
  20. String inputLine;
  21. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
  22. new FileOutputStream("result.xml")));// 将结果存放的位置
  23. while ((inputLine = in.readLine()) != null)
  24. {
  25. System.out.println(inputLine);
  26. bw.write(inputLine);
  27. bw.newLine();
  28. }
  29. bw.close();
  30. in.close();
  31. httpConn.disconnect();
  32. }

soap.xml代码如下:

  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错误

错误代码:

  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)

错误语句指向

  1. InputStreamReader is = new InputStreamReader(httpConn.getInputStream());

而网上其他大部分文章都没有给解决方法,或者给了其他的解决方法,我就在这边分享一下这个问题的详细解决方法。

解决流程(干货

首先应该确认具体的错误,通过下面的语句可以了解InputStream的错误详情。

  1. InputStream is = httpConn.getErrorStream();    //通过getErrorStream了解错误的详情,因为错误详情也以XML格式返回,因此也可以用JDOM来获取。

这个语句其实也是从请求的服务方取回的错误信息,实质也是xml内容,用上面的BufferReader那一连串的语句解析出具体内容,然后输出查看,具体代码如下:

  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();

错误详情输出如下:

  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(就是添加了命名空间)

  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代码
  1. package soap;
  2. import java.io.*;
  3. import java.net.HttpURLConnection;
  4. import java.net.URL;
  5. /**
  6. * Created by cc on 2016/10/21.
  7. */
  8. public class HelloSoap {
  9. public static void main(String[] args) throws Exception
  10. {
  11. String urlString = "http://localhost:9000/HelloWorld?wsdl";//wsdl文档的地址
  12. URL url = new URL(urlString);
  13. HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();//打开连接
  14. //String soapActionString = "http://localhost:9000/HelloWorld/sayHelloWorldFrom";//Soap 1.1中使用
  15. String xmlFile = "soap_xml\\soap.xml";//要发送的soap格式文件
  16. File fileToSend = new File(xmlFile);
  17. byte[] buf = new byte[(int) fileToSend.length()];// 用于存放文件数据的数组
  18. new FileInputStream(xmlFile).read(buf);
  19. //Content-Length长度会自动进行计算
  20. httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
  21. //httpConn.setRequestProperty("soapActionString",soapActionString);//Soap1.1使用 其实完全可以不需要
  22. httpConn.setRequestMethod("POST");
  23. httpConn.setDoOutput(true);
  24. httpConn.setDoInput(true);
  25. OutputStream out = httpConn.getOutputStream();
  26. out.write(buf);
  27. out.close();
  28. if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
  29. {
  30. InputStreamReader is = new InputStreamReader(httpConn.getInputStream());
  31. BufferedReader in = new BufferedReader(is);
  32. String inputLine;
  33. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
  34. new FileOutputStream("result.xml")));// 将结果存放的位置
  35. while ((inputLine = in.readLine()) != null)
  36. {
  37. System.out.println(inputLine);
  38. bw.write(inputLine);
  39. bw.newLine();
  40. }
  41. bw.close();
  42. in.close();
  43. }
  44. else{
  45. //如果服务器返回的HTTP状态不是HTTP_OK,则表示发生了错误,此时可以通过如下方法了解错误原因。
  46. InputStream is = httpConn.getErrorStream();    //通过getErrorStream了解错误的详情,因为错误详情也以XML格式返回,因此也可以用JDOM来获取。
  47. InputStreamReader isr = new InputStreamReader(is,"utf-8");
  48. BufferedReader in = new BufferedReader(isr);
  49. String inputLine;
  50. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
  51. new FileOutputStream("result.xml")));// 将结果存放的位置
  52. while ((inputLine = in.readLine()) != null)
  53. {
  54. System.out.println(inputLine);
  55. bw.write(inputLine);
  56. bw.newLine();
  57. bw.close();
  58. }
  59. in.close();
  60. }
  61. httpConn.disconnect();
  62. }
  63. }

java使用POST发送soap报文请求webservice返回500错误解析的更多相关文章

  1. python通过http请求发送soap报文进行webservice接口调用

    最近学习Python调用webservice 接口,开始的时候主要采用suds 的方式生产client调用,后来发现公司的短信接口采用的是soap报文来调用的,然后开始了谷歌,最后采用httplib ...

  2. JQuery请求WebService返回数据的几种处理方式

    打开自己的博客仔细浏览了一番,发现已经好久没有写博客了,由于最近一直比较忙碌懈怠了好多.默默反省三分钟.......言归正传,现在就对最近在学习webservice的过程中遇到的几种类型的问题中我的理 ...

  3. dotnet webservice处理数据量过大,ajax请求返回500错误解决方案

    ajax请求webservice返回json数据,数据规模过大时ajax请求会得到500的响应,webservice+ajax处理大规模的数据需要在web.config中进行如下配置: <sys ...

  4. Java 用HTTP的方式发送JSON报文请求

    前言: 项目调用第三方接口时,通常是用socket或者http的通讯方式发送请求:http 为短连接,客户端发送请求都需要服务器端回送响应,请求结束后,主动释放链接.Socket为长连接:通常情况下S ...

  5. Node.js 使用 soap 模块请求 WebService 服务接口

    项目开发中需要请求webservice服务,前端主要使用node.js 作为运行环境,因此可以使用soap进行请求. 使用SOAP请求webservice服务的流程如下: 1.进入项目目录,安装 so ...

  6. Kettle通过Http post请求webservice接口以及结果解析处理

    kettle中有两种方式请求webservice服务,一个是Web服务查询,但是这个有缺陷,无法处理复杂的需求,遇到这种情况就需要用Http post来处理了. 网上也有很多关于Http post请求 ...

  7. curl post请求总是返回417错误

    在进行post请求的时候, curl总是返回417错误 在使用curl做POST的时候, 当要POST的数据大于1024字节的时候, curl并不会直接就发起POST请求, 而是会分为俩步. 发送一个 ...

  8. HttpURLConnection 直接发送soap消息调用webservice

    httpConn = (HttpURLConnection) new URL(urlString).openConnection();    httpConn.setRequestProperty(& ...

  9. ajax 请求 服务器 响应内容过长 返回500错误的解决方法

    在web.config试试加上 <system.web.extensions> <scripting> <webServices> <jsonSerializ ...

随机推荐

  1. notepad++去空格空行技巧

    选择视图显示所有字符,替换成空的就行

  2. win7 秘钥

    链接 安装好Windows7后右击计算机--属性--更改产品密匙 输入以下密匙; RHTBY-VWY6D-QJRJ9-JGQ3X-Q2289 HT6VR-XMPDJ-2VBFV-R9PFY-3VP7R ...

  3. php session在高并发时可能存在的问题。

    如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行.这是因为在默认情况下,PHP使用文件存储Session数 ...

  4. 关于Sublime Text不能在打开方式中显示并且不能被设置成默认打开方式的问题

    解决方法: 1. Windows 输入 regedit 后 回车 打开注册表 2.找到 "HKEY_CLASSES_ROOT\Applications\sublime_text.exe\sh ...

  5. 使用 event.preventDefault 拦截表单的提交

    event.preventDefault() 方法 W3C 官方的定义是:取消事件的默认动作,不单单可以拦截表单的提交,<a>标签的跳转, <input>标签的输入等等默认动作 ...

  6. Python--csv文件处理

    CSV(Comma-Separator Values)逗号分割值,由于是纯文本文件,任何编辑器都可以打开.下面用csv和pandas两种方式进行csv文件操作 原始csv文件内容 Supplier N ...

  7. bzoj 3598 方伯伯的商场之旅

    Written with StackEdit. Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 \(i\) 的人面前 ...

  8. Dijkstra算法(带路径模板)

    个人心得:Dijkstra算法是贪心思想的一种延伸,注意路径pre,pre数组表示此时最短路径中的前一个顶点.每次更新到目的点时更新: 从源点出发,更新路径,然后找出此时最短的点,然后以这个点为头,看 ...

  9. Winform、WPF、Silverlight、MFC区别与联系

    WinForm 在Windows中,诸如窗体绘制等功能由GDI(图形设备接口)实现,放在操作系统内核中.Windows Forms在底层使用的是GDI+.GDI+是GDI的“面向对象包装”,使用C++ ...

  10. webpack中多模块依赖

    多模块依赖 刚才的例子,我们仅仅是跑通了webpack通过entry.js入口文件进行打包的例子.下面我们就来看一下它是否真的支持CommonJs和AMD两种模块机制呢?下面我们新建多几个js文件吧! ...