java调用webservice:dotNet使用WSE3.0调用java的web服务来源: 发布时间:星期四, 2009年2月12日 浏览:345次 评论:0
本文主要描述使用.net客户端java写服务端webservice并且使用了WSI协议中UserNameToken验证思路方法 先给出要POST包格式: <soap:Envelope xmlns:soap="…"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-7f2cd499-d67d-4052-87c3-870833c2fb06"> <wsse:Username>much</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">123456</wsse:Password> </wsse:UsernameToken> </wsse:Security> <RequestSOAPHeader xmlns="…."> < otherheader>xxxx</otherheader> </RequestSOAPHeader> </soap:Header> <soap:Body> …….. </soap:Body> </soap:Envelope> 安装WSE3.0版本在VS项目中添加Microsoft.Web.Services3引用. 首先导入有java服务端生成wsdl文件生成客户段代理类 这里导入wsdl文件有两种思路方法: 、在VS提供命令提示符中编译WSDL文件 给个例子: Wsdl /language:CS /n:my /out:myProxyClass.cs C:/myProject/wsdl/webservice.wsdl 最后个参数是本地绝对路径是个文件也可以是个网络路径 2、在项目右键中添加WEB引用输入本地WSDL绝对路径 注意:用VS引用生成代理类名称为Reference.cs可以在项目目录下找到 然后修改本地生成代理类在最后个using下面添加 [.Xml.Serialization.XmlTypeAttribute(Namespace = "…")] [.Xml.Serialization.XmlRootAttribute(Namespace = "…", IsNullable = false)] public RequestSOAPHeader : .Web.Services.Protocols.SoapHeader { public otherheader; } 将.Web.Services.Protocols.SoapHttpClientProtocol替换为Microsoft.Web.Services3.WebServicesClientProtocol 在代理类构造上面private bool useDefaultCredentialsSetExplicitly这行代码下面添加public RequestSOAPHeader ServiceAuthHeaderValue这行代码注意要在类里面作为服务类公共 最后找到你要那个服务思路方法在上面添加 [.Web.Services.Protocols.SoapHeaderAttribute("ServiceAuthHeaderValue")]这行代码注意ServiceAuthHeaderValue是声明公共成员 如果你找不到你可以搜索下类似[.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=.Web.Services.Protocols.SoapParameterStyle.Bare)]代码对就在这上面或下面添加 到这里就修改好了代理类了注意保存备份下不要更新代理类否则代理类又会还原回去了 接着设置下WSE配置右击项目选择WSE tings 3.0… 勾选General下Enable this project for web service enhancements 选择Policy勾选Enable Policy然后点Add我这里已经添加了没添加时候是空 填写Policy名称为ClientPolicy在向导中依次选择Secure a client application+username ->Specy username token in code ->None 最后生成Policy信息如下: 然后到Security选项卡里点击Security Tokens Managers中Add在下拉框中选择Username Token Manager会自动生成其他信息点OK保存即可 看下你app.config中有没有如下信息: <configSections> <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> ……. </sectionGroup> </configSections> <microsoft.web.services3> <policy fileName="wse3policyCache.config" /> <security> <securityTokenManager> <add type="Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" ="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken" /> </securityTokenManager> </security> </microsoft.web.services3> wse3policyCache.config里信息如下: <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy"> <extensions> <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <extension name="usernameOverTransportSecurity" type="Microsoft.Web.Services3.Design.UsernameOverTransportAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </extensions> <policy name="ClientPolicy"> <usernameOverTransportSecurity /> <requireActionHeader /> </policy> </policies> 下面是服务思路方法关键代码: //服务对象 ProxyService sendws = ProxyService; //添加SOAP头 ProxyService.RequestSOAPHeader Soapheader = ProxyService.RequestSOAPHeader; Soapheader.otherheader=”xxx”; sendws.ServiceAuthHeaderValue = Soapheader; //设置协议 UsernameToken token = UsernameToken("username", "password", PasswordOption.SendPlainText); sendws.SetClientCredential(token); sendws.SetPolicy("ClientPolicy"); sendws.Url = "....."; sendws.webmethod ; 到这里使用Fiddler截包发现SOAP包头中信息出现了Action, Timestamp等信息为了得到更加灵活SOAP头就必须重写SoapFilter类 在你项目中添加个类UsernameClientAssertion: UsernameClientAssertion : SecurityPolicyAssertion { public UserName; public PassWord; public UsernameClientAssertion( UserName, PassWord) { this.UserName = UserName; this.PassWord = PassWord; } public override SoapFilter CreateClientOutputFilter(FilterCreationContext context) { ClientOutputFilter(this, context); } public override SoapFilter CreateClientInputFilter(FilterCreationContext context) { null; } public override SoapFilter CreateServiceInputFilter(FilterCreationContext context) { null; } public override SoapFilter CreateServiceOutputFilter(FilterCreationContext context) { null; } } 新建个ClientOutputFilter ClientOutputFilter : SoapFilter { private UsernameClientAssertion parentAssertion; private FilterCreationContext filterContext; public ClientOutputFilter(UsernameClientAssertion parentAssertion, FilterCreationContext filterContext) { this.parentAssertion = parentAssertion; this.filterContext = filterContext; } public override Microsoft.Web.Services3.SoapFilterResult ProcessMessage(SoapEnvelope envelope) { XmlElement securityElement = envelope.CreateElement("wsse", "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); XmlAttribute mustUnderstandAttribute = envelope.CreateAttribute(envelope.DocumentElement.Prefix, "mustUnderstand", envelope.DocumentElement.NamespaceURI); mustUnderstandAttribute.Value = "true"; UsernameToken userToken = UsernameToken(parentAssertion.UserName, parentAssertion.PassWord, PasswordOption.SendPlainText); securityElement.AppendChild(userToken.GetXml(envelope)); securityElement.FirstChild.RemoveChild(securityElement.FirstChild.FirstChild.NextSibling.NextSibling); securityElement.FirstChild.RemoveChild(securityElement.FirstChild.FirstChild.NextSibling.NextSibling); //envelope.CreateHeader.RemoveAll; envelope.CreateHeader.PrependChild(securityElement); envelope.CreateHeader.RemoveChild(envelope.CreateHeader.FirstChild.NextSibling.NextSibling); envelope.CreateHeader.RemoveChild(envelope.CreateHeader.FirstChild.NextSibling.NextSibling); envelope.CreateHeader.RemoveChild(envelope.CreateHeader.FirstChild.NextSibling.NextSibling); envelope.CreateHeader.RemoveChild(envelope.CreateHeader.FirstChild.NextSibling.NextSibling); SoapFilterResult.Continue; } } 简单说下上面代码创建灵活SOAP头就在思路方法public override Microsoft.Web.Services3.SoapFilterResult ProcessMessage(SoapEnvelope envelope)里 可以看得出就是对XML操作啦如果调不出你要包就设个断点F10F10 修改下原来代码为: //服务对象 ProxyService sendws = ProxyService; //添加SOAP头 ProxyService.RequestSOAPHeader Soapheader = ProxyService.RequestSOAPHeader; Soapheader.otherheader=”xxx”; sendws.ServiceAuthHeaderValue = Soapheader; //设置协议 UsernameToken token = UsernameToken("username", "password", PasswordOption.SendPlainText); Policy ProvideUsernameToken = Policy; ProvideUsernameToken.Assertions.Add( UsernameClientAssertion("do_user", "do_user")); UsernameTokenManager tokenm = UsernameTokenManager; sendws.SetClientCredential(token); sendws.SetPolicy(ProvideUsernameToken); sendws.Url = "..."; sendws.webmethod ; 这样就重写了SOAP头输出部分了 整理总结 WSE3.0只能在VS2005下才能集成在项目中VS2008不能支持我的前试着直接改写app.config和wse3policyCache.config里内容都失败了觉得可能是证书生成有问题WSE也提供手动生成证书但是这么多东西都用手动生成恐怕不太容易稍有差错就调试不出来了 在VS2008下已经使用WCF代替了WSE了使用了绑定设置思路方法我也没有试出来如果你试出来了请告诉我谢谢 0
相关文章读者评论发表评论 |
|