博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
http动态调用webserive
阅读量:6233 次
发布时间:2019-06-21

本文共 3684 字,大约阅读时间需要 12 分钟。

   前言

   传统方式调用WebService是直接引用服务,生成客户端代理类类,这种方式将ws进行了再次封装,并以代理的方式进行调用,这种方式的优点是简单,方便。

   但是此种方式不足的地方是,当对方ws接口变更时,这边引用的服务同时也需要编译并部署,或者我调用方这边想动态指定不同服务地址时,此方式就不太适应这种场景了。

    有一种方式是动态调用ws的方式。就是通过ws的服务描述获取生成客户端的代理并动态编译,通过反射生成实例对象,并完成ws的调用。大致代码如下

1 ///   2         /// 动态调用WebService  3         ///   4         /// WebService地址  5         /// 类名  6         /// 方法名(模块名)  7         /// 参数列表  8         /// 
object
9 public static object InvokeWebService(string url, string classname, string methodname, object[] args)10 {11 string @namespace = "ServiceBase.WebService.DynamicWebLoad";12 if (classname == null || classname == "")13 {14 classname = WebServiceHelper.GetClassName(url);15 }16 //获取服务描述语言(WSDL) 17 WebClient wc = new WebClient();18 Stream stream = wc.OpenRead(url + "?WSDL");19 ServiceDescription sd = ServiceDescription.Read(stream);20 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();21 sdi.AddServiceDescription(sd, "", "");22 CodeNamespace cn = new CodeNamespace(@namespace);23 //生成客户端代理类代码 24 CodeCompileUnit ccu = new CodeCompileUnit();25 ccu.Namespaces.Add(cn);26 sdi.Import(cn, ccu);27 CSharpCodeProvider csc = new CSharpCodeProvider();28 ICodeCompiler icc = csc.CreateCompiler();29 //设定编译器的参数 30 CompilerParameters cplist = new CompilerParameters();31 cplist.GenerateExecutable = false;32 cplist.GenerateInMemory = true;33 cplist.ReferencedAssemblies.Add("System.dll");34 cplist.ReferencedAssemblies.Add("System.XML.dll");35 cplist.ReferencedAssemblies.Add("System.Web.Services.dll");36 cplist.ReferencedAssemblies.Add("System.Data.dll");37 //编译代理类 38 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);39 if (true == cr.Errors.HasErrors)40 {41 System.Text.StringBuilder sb = new StringBuilder();42 foreach (CompilerError ce in cr.Errors)43 {44 sb.Append(ce.ToString());45 sb.Append(System.Environment.NewLine);46 }47 throw new Exception(sb.ToString());48 }49 //生成代理实例,并调用方法 50 System.Reflection.Assembly assembly = cr.CompiledAssembly;51 Type t = assembly.GetType(@namespace + "." + classname, true, true);52 object obj = Activator.CreateInstance(t);53 System.Reflection.MethodInfo mi = t.GetMethod(methodname);54 return mi.Invoke(obj, args);55 }56 57 private static string GetClassName(string url)58 {59 string[] parts = url.Split('/');60 string[] pps = parts[parts.Length - 1].Split('.');61 return pps[0];62 }
View Code

   但是这种方式,最明显的方式就是性能较差,每次都要重新生成反射调用,所以一般情况不用它。

     那还有别的方法吗?

     那我就来说说今天在工作中用到的方法。

    soap请求

    首先需要知道传统的调用方式的通行协议是关键,ws底层也是走的http方式,只是加了多加了soap协议在里面,那怎么拿到它的交互协议呢,有一个神器叫fiddler,它可以监测http请求和响应信息。有了它,就有了协议了,剩下就是拼装协议了。

    仔细观察协议后 发现它的交互结构如下

POST /WebServiceTest/Service1.asmx HTTP/1.1Host: localhostContent-Type: text/xml; charset=utf-8Content-Length: lengthSOAPAction: "http://tempuri.org/HelloWorld" 
string
string
SOAPAction这个就是表示请求的具体方法,在请求流中,在写入上面的基于xml的soap协议,接下来就可以发起请求了,顺利的话就能拿到响应了。  做事有根有据,仔细并专注,不经意间,就能成功不远了。

转载于:https://www.cnblogs.com/JaggerMan/p/4893253.html

你可能感兴趣的文章
Android MaoZhuaWeiBo开发Service抓取个人信息-2
查看>>
Codefoces 436 B. Om Nom and Spiders
查看>>
流程控制------if else分支语句
查看>>
禁用Clusterware在系统启动后自己主动启动
查看>>
Storm编程入门API系列之Storm的Topology默认Workers、默认executors和默认tasks数目
查看>>
Json转java对象和List集合
查看>>
PHP操作MongoDB数据库具体样例介绍(增、删、改、查) (六)
查看>>
关于Unity中的模型描边与Shader切换(专题二)
查看>>
《淘宝技术这十年》读后感
查看>>
程序员经常加班的真正原因
查看>>
windows系统下如何正确安装Cygwin(图文详解)
查看>>
SpringBoot接口服务处理Whitelabel Error Page
查看>>
mysql创建唯一索引
查看>>
Vijos1935不可思议的清晨题解
查看>>
Android Studio修改默认Activity继承AppCompatActivity
查看>>
Servlet和Android网络交互基础(3)
查看>>
javascript:void(0) 含义
查看>>
<<、|=、&的小例子
查看>>
愿Linux红帽旋风吹得更加猛烈吧!
查看>>
Secret Code
查看>>