使用CURL请求WebService
之前有一篇文章(通过SSL\HTTPS调用WebService)介绍过如何使用HTTPS协议调用WebService,使用那篇文章介绍的方法确实可以解决大部分问题,但是总有一小波问题必须通过其它手段解决。
按理论来说,WebService是跨平台数据通信的最佳解决方案,而且实际上当我们解决两个独立系统的数据互通或互调时,首先想到的方案也必定是使用WebService。但是有时候天不遂人愿,比如我就碰到了一例:A系统使用ASP.NET开发,并且部署于Windows平台上,现在需要调用B系统中的数据,而B系统使用JSP开发且部署于Linux系统上,然后噩梦开始了,在VS的项目中添加Web引用时,就会出现如下的错误:
添加不上引用怎么办,试试模拟HTTP-POST请求吧,而且的确可以这么做,只不过麻烦一些,信心满满的写好代码,然后运行,直接报错,而且是相同的错误:
怎么办?到这其实已经没有办法了,因为这是HttpWebRequest对象抛出来的底层错误,其实这个错误是由于两边安全通道无法建立所引起的,经过资料的查找应该是.NET使用的证书和Java使用的证书协议不同而引起的,大概是这么个意思,反正你就是无法解决了,因为你不可能改变HttpWebRequest的源码。
至此,就需要换一个思路了,能不能不使用.NET提供的通信类来实现调用,换一个第三方组件,这个组件必须跟.NET毫无关系,于是Google或者Baidu吧。通过反复的查找,找到了CURL,它的介绍如下:
curl是利用URL语法在命令行方式下工作的开源文件传输工具。它被广泛应用在Unix、多种Linux发行版中,并且有DOS和Win32、Win64下的移植版本。licurl则提供给开发者,用于使用C++跨平台的开发各种网络协议的请求及响应。
C#调用C++组件理论上是可以的,但是当前没工夫看它的源码和使用,重要的是实现,如何请求WebService并获得返回的数据。
至其官网下载Win平台下的版本,同时需要下载OpenSSL的动态链接库,将所需的文件放置在同一目录下,如下图:
在使用之前需要了解一下curl工具的有效参数的意义(注意,参数区分大小写):
-k:允许不使用证书请求SSL站点。
-H:自定义头信息传递给服务器。
-d:以HTTP POST方式传送数据。
假设WebService的发布地址为“https://123.com/loginservice”,请求命令如下:
- curl -k -H "Content-Type:text/xml;charset=utf-8;SOAPAction:Namespace:login" -d "数据主体" https://123.com/loginservice
返回的数据会跟在此命令之下,这里需要注意的是,如果请求WebService,一般发送的数据主体都为xml格式的字符串,而且其中肯定包含如同下面的字符:
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
将此字符串直接作为数据主体输入,肯定会报错的,正确的格式为:
- curl -k -H "Content-Type:text/xml;charset=utf-8;SOAPAction:Namespace:login" -d "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" https://123.com/loginservice
最后,整体的思路应该是这样的:
1.获取curl工具,确保能够正确运行。
2.编写所需的curl命令,并且能够通过测试。
3.使用System.Diagnostics.Process启动cmd命令行工具,调用curl命令请求WebService。
4.从该cmd工具的输出流中获取返回的数据。
5.解析获得有效数据。
至此,问题暂时可以解决,其实比较好的办法是使用C++封装一个动态链接库,然后在项目中引用,这样既稳定又高效,使用CMD命令行这种方式只是一种暂时的替代方式。
这得是误导了多少人啊
你可以说说哪里误导了,也能为别人指条明路。