调用WebService,最简单的办法当然是直接添加WEB引用,然后自动产生代理类,但是在调用JAVA的WebService时并没有这么简单,特别是对于SoapHeader的处理,在网上也有相关资料,但是都整理的不够清晰明了。根据网上的资料,个人也对各种方法进行了尝试,费了不少精力,为此特将自己的解决方法进行总结一下,以备以后需要以及相关朋友参考。

先说说的思路:

1、先用soapUI进行测试,这个工具会自动生成调用某个方法的XML。

2、把soapUI生成的XML作为模版,自己也生成一个一模一样的XML并为参数节点赋好值。

3、将这个XML通过http直接发送给WebService。

4、接收返回的XML进行处理。

这样做最大的好处就是可以自己很轻松的控制XML格式,最开始的时候我是通过添加引用的方式去调用某个方法一直失败,但是用soapUI去测试这个方法又是可以成功调用的,折腾了半天,最后通过抓包的方式对发送的数据进行对比,发现两者发送的XML相差甚远,好了废话不说了,就拿一个小实例来演示这个过程吧。

首先,通过soapUI工具测试调用WebService里公用的WebSercie(http://www.webxml.com.cn/WebServices/WeatherWebService.asmx)中的一个名为getSupportCity的方法,生成的XML如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://WebXml.com.cn/"><soapenv:Header/><soapenv:Body><web:getSupportCity><!--Optional:--><web:byProvinceName>北京</web:byProvinceName></web:getSupportCity></soapenv:Body>
</soapenv:Envelope>

上面加粗标示的地方就是我们要修改赋值的地方,大家看到了吧,如果用添加引用自动生成代理类的方式,要产生这样格式的XML有多难控制了吧,但是如果全部用代码来生成也不是一件容易的事,个人用了一个比较巧妙的办法:

在项目中添加一个名为“getSupportCity”的xml文件,将上面的XML粘贴上去,然后再将这个XML文件作为内嵌资源(在这个的文件属性里面的‘生产操作’选择‘嵌入的资源’),使用的时候直接加载这个XML文件,然后按逻辑处理需要修改的地方(其实就是XML文档操作)。使用内嵌资源是为了不让外面看到我们的那个XML文件,以防被修改了什么的。

下面看看调用的代码实现吧:(为了理解方便清晰,我们用跟WebService上一模一样的方法名和参数)

   /// <summary>/// 天气预报/// </summary>/// <param name="id">居民id</param>public static void getPopCheckedInfo(){String ServerUrl = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx";//得到WebServer地址Hashtable pars = new Hashtable();//用来存放参数pars["byProvinceName"] = "北京";XmlDocument xml = QuerySoapWebService(ServerUrl, "getSupportCity", pars);//这个是对返回的XML文件处理,我删掉了,处理完后返回一个居民的实体对象          }

 WebSvcCaller.QuerySoapWebService方法代码:

  public static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars){HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);request.Method = "POST";request.Accept = @"gzip,deflate";request.ContentType = @"text/xml;charset=utf-8";request.UserAgent = @"Jakarta Commons-HttpClient/3.1";request.Credentials = CredentialCache.DefaultCredentials;request.Timeout = 10000;byte[] data = EncodeParsToSoap(Pars, MethodName);WriteRequestData(request, data);//将处理成字节组的XML写到流中发送到服务端XmlDocument doc = new XmlDocument();doc = ReadXmlResponse(request.GetResponse());//读取服务端返回的结果return doc;}

EncodeParsToSoap(Pars, MethodName),处理XML文件方法的代码:(以下仅供参考,大家根据自己的实际情况变动)

 private static Hashtable hshtableXML = new Hashtable();/// <summary>/// 处理要发送的XML文档/// </summary>/// <param name="Pars">参数</param>/// <param name="MethodName">方法名</param>private static byte[] EncodeParsToSoap(Hashtable Pars, String MethodName){XmlDocument xml = null;if (hshtableXML.ContainsKey(MethodName)){//如果已经加载过,则从缓存中读取xml = (XmlDocument)hshtableXML[MethodName];}else{//如果还未加载则进行加载,并放入缓存//从资源文件得到文件流Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("异步调用.file." + MethodName + ".xml");xml = new XmlDocument();xml.Load(stream);hshtableXML.Add(MethodName, xml);}//修改参数的值foreach (DictionaryEntry de in Pars){XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");nsmgr.AddNamespace("web", "http://WebXml.com.cn/");Hashtable subpars = de.Value as Hashtable;if (subpars == null){string subNode = "soapenv:Envelope/soapenv:Body/web:" + MethodName + "/web:" + de.Key.ToString();XmlNode node = xml.SelectSingleNode(subNode, nsmgr);node.InnerText = de.Value.ToString();}else{foreach (DictionaryEntry subde in subpars){string subNode = "soapenv:Envelope/soapenv:Body/ws:" + MethodName + "/" + de.Key.ToString() + "/" + subde.Key.ToString();XmlNode node = xml.SelectSingleNode(subNode, nsmgr);node.InnerText = subde.Value.ToString();}}}//将修改后的XML文件保存到流中//这样做还可以保证发送的XML文件也是格式化的那种形式,而不是一整行//如通过OuterXml获取的就是一整行,这样也可能会导致服务端解析失败,个人这次就碰到这种情况了MemoryStream outStream = new MemoryStream();xml.Save(outStream);byte[] buffer = new byte[outStream.Length];byte[] temp = outStream.GetBuffer();for (int i = 0; i < buffer.Length; i++){buffer[i] = temp[i];}outStream.Close();return buffer;}

最后还有WriteRequestData、ReadXmlResponse两个方法的代码:

  /// <summary>/// 写到流中,发送给服务端/// </summary>/// <param name="request">HttpWebRequest连接对象</param>/// <param name="data">要写入连接流发给服务端的内容</param>private static void WriteRequestData(HttpWebRequest request, byte[] data){request.ContentLength = data.Length;Stream writer = request.GetRequestStream();writer.Write(data, 0, data.Length);writer.Close();}/// <summary>/// 读取服务端返回的结果/// </summary>private static XmlDocument ReadXmlResponse(WebResponse response){StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);String retXml = sr.ReadToEnd();sr.Close();XmlDocument doc = new XmlDocument();doc.LoadXml(retXml);return doc;}

注:在实际开发过程中,如果服务器不是标准的WebService,那么返回的数据格式不一定是XML,可能是很难解析的字符串,

出现这种情况解决办法,

第一,让服务器修改接口,返回标准XML格式;

第二:按字符串硬处理

示例下载

参考文档

http://www.cnblogs.com/fengyao/archive/2010/06/14/1749383.html

转载于:https://www.cnblogs.com/yxhblog/p/7207440.html

.NET调用JAVA的WebService方法相关推荐

  1. android 调用java类_Android中在WebView里实现Javascript调用Java类的方法

    搜索热词 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法 ...

  2. oracle 执行java_oracle调用JAVA类的方法

    oracle调用JAVA类的方法主要有以下三种: 1. 用loadjava方法装载: 可能是调试方便,据说这种方法比较通用. c:\test\hello.java public class hello ...

  3. webview 调用java_Android中在WebView里实现Javascript调用Java类的方法

    为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法即可映射一 ...

  4. 【Linux】shell调用Java程序main方法通过crontab定时执行

    来源:https://blog.csdn.net/coolcooldool/article/details/51775105 最近一个项目需要写一个batch定时读取文件往数据库里插入记录,第一次写, ...

  5. 比较两种php调用Java对象的方法

    Java语言功能强大,因此在许多情况下在php中来调用Java的功能将十分有用.在php中调用Java语言有两种方法,一种是使用php中 的Java扩展模块,另一种是使用minij2ee应用服务器提供 ...

  6. C#调用Java的WebService时添加身法认证信息的方法

    Java生成的WebService要求在调用时在http的header里必须带上Authorization:Basic xxxxxxxxxxxxxxx的认证信息 因为是在添加Web Reference ...

  7. axis调用java实现webservice实例

    一: 首先创建个WEB工程,然后: http://ws.Apache.org/axis/网站下载Axis安装包.当然还依赖其他包的,我这里在附件里上传了所有应用到得包,方便大家. 二: 然后就写wsd ...

  8. UDF函数,hive调用java包简单方法

    UDF函数,是hadoop在强大的大数据批量导入导出操作之余,为了满足复杂的数据逻辑操作留下的接口 核心思想:不管是UDF函数还是自定义处理jar包,都是要放置在hadoop服务器上的,相当于hado ...

  9. DWR框架--让前端JS代码调用JAVA后端的方法

    目录 1.DWR框架简介 2.使用步骤 2.1.pom.xml导入包 2.2.配置web.xml文件 2.2.1.先了解dwr的jar包(不同版本不一样,需注意) 2.2.2.在web.xml中增加d ...

最新文章

  1. solr单机版的搭建
  2. 智能音箱 之 平台方案简介
  3. mongose + express 写REST API
  4. CVPR2021 Oral|只用静态图,实时渲染出丝滑3D效果
  5. 查看mysql数据用户权限_查看MYSQL数据库中所有用户及拥有权限
  6. eclipse 的project explorer问题,这个怎样把localFileSystem去掉,
  7. git上传代码和下拉
  8. 【Linux】tee命令
  9. 3dmax用vr渲染还是cr渲染器?
  10. 斐讯路由器K2最新刷机教程
  11. Mysql性能优化:什么是索引下推?
  12. 安全测试-渗透性测试
  13. MP地面站二次开发教程(二)MP的框架与修改
  14. js实现图片无缝滚动特效
  15. oracle存储过程新手学习
  16. 超好看的css动画特效实现
  17. 软件智能:aaas系统对AI的诠释-AI的可能的三个取向和必然的一个成果(演绎逻辑-必然的推理-的两个独立性:推论和定论)
  18. skywalking plugin 开发初探 ONS plugin 实践
  19. springboot shiro设置session过期时间
  20. 实现手机root的心路历程之完成Oppo R7s root功能-亲测有用

热门文章

  1. [讨论]你的女朋友值多少钱?
  2. usaco Postal Vans(dp)
  3. php excel 追加写入,phpexcel写入追加已有的excel文件
  4. 码云nacos下载_nacos安装,配置以及持久化
  5. 径向基函数神经网络_基于RBF神经网络的网络安全态势感知预测研究
  6. 9开启线程日志_GC 日志分析
  7. android 监控app卸载,Android应用监听自身卸载
  8. mongodb在mysql中怎么用,mongoDB数据库基本操作
  9. android picasso源码下载,Picasso:一个专为Android制作的强大的图片下载和缓存库
  10. C++ 容器1 vector