定义和使用 Web 服务都不是一件费力的事情,尤其在当前框架和工具的支持下更加容易。一般来说,常见情况下我们都会使用同一个开发语言、框架和工具来开发 Web 服务和调用服务的客户端。但是由于技术或非技术上的原因,又需要我们在不同的平台上发布、订阅彼此的 Web 服务。就在昨天,应同事的需要,就在 .NET 平台上使用 C# 编写一段调用部署在 XFire 上的 Web 服务的客户端代码。之前认为 Web 服务/SOAP 协议本来就是在开放的精神下设计的,因此跨平台调用也不会有多麻烦,但是也正是因为之前对 XFire 上的 Web 服务细节不太了解,浪费了我宝贵的几个小时,在此作以记录,另一方面也希望能为其它人提供些许帮助,免得大家无谓浪费时间。
在这里要说明的是如何在 .NET (C#)代码中定义正确的 SOAP 头来满足 XFire Web 服务中使用自定义 Handler 验证操作
。这包括两种方式:
- 基于 .NET WCF 服务模型
的客户端服务代理。
- 基于 .NET Web 服务模型
的客户端服务代理。
话说两头,先表服务端。XFire Web 服务可以提供四种验证的方式,它们分别是:
- HTTP 验证
- JSR181 规范
- 自定义 Handler 代码
- WS-Security 规范
在这里说的就是自定义 Handler 代码验证方式,当前 Web 服务中的 Handler 代码是根据 XFire 提供的示例代码改造的,很容易理解。
public class AuthenticationHandler extends AbstractHandler {
// Namespace define, come from services.xml configuration.
private final static Namespace TOKEN_NS = Namespace.getNamespace("demoService");
public void invoke(MessageContext context) throws Exception {
Element header = context.getInMessage().getHeader();
if (header == null) {
throw new XFireFault("Request must include company authentication token.", XFireFault.SENDER);
}
Element token = header.getChild("AuthenticationToken", TOKEN_NS);
if (token == null) {
throw new XFireFault("Request must include authentication token.", XFireFault.SENDER);
}
Element license = token.getChild("license", TOKEN_NS);
if (license == null) {
throw new XFireFault("license is null.", XFireFault.SENDER);
}
String licenseValue = license.getValue();
if (licenseValue == null) {
throw new XFireFault("license value is null.", XFireFault.SENDER);
}
try {
// Other check code.
} catch(Exception e) {
throw new XFireFault("Authentication Failed.", XFireFault.SENDER);
}
}
}
上面代码中有多步检查动作,其中关于内容检查的代码忽略了,留下的主要是对 SOAP 报文头中携带元素的存在性检查的代码。客户端调用要想通过该检查,首先要有 SOAP 头并携带必要的元素,其次才是元素内容正确。由于元素内容正确性检查涉及具体算法逻辑,这里就忽略不关注了。这里主要想说明是怎么保证 .NET 客户端发送 SOAP 报文头中携带必要的元素,根据上面代码可知,这里必须包括三部分:
- SOAP 报文必须有头信息
- 头中必须携带 AuthenticationToken 元素
- AuthenticationToken 元素中必须包括 license 子元素
另外要说明,AuthenticationHandler 类是在 services.xml 文件中配置生效的:
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>demoService</name>
<namespace>http://webservice.lzy.iteye.com</namespace>
<serviceClass>com.lzy.javaeye.webservice.IWebService</serviceClass>
<implementationClass>com.lzy.javaeye.webservice.impl.WebService</implementationClass>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
<inHandlers>
<handler handlerClass="com.lzy.javaeye.webservice.AuthenticationHandler"/>
</inHandlers>
</service>
</beans>
其中配置的 inHandlers 元素就是为 demoService 服务的添加了自定义 Handler 验证,即 AuthenticationHandler 类。
服务端就是上面这些,下面就要分两方面(WCF 服务模型和 Web 服务模型)来说明 .NET调用的事了。
先说在 .NET 中通过 WCF 服务框架调用 XFire Web 服务。
在 .NET 3.5 中微软提出了 WCF 框架,在这种基于服务的通信框架中包括了很多概念,契约就是重要的一个。WCF 将所有服务都定义为契约,它与平台无关,是描述服务功能的标准方式。WCF 契约分为四种:
- 服务契约(Service Contract)
- 数据契约(Data Contract)
- 错误契约(Fault Contract)
- 消息契约(Message Contract)
结合这个场景来说吧,调用一次服务,对于 WCF 来说属于使用规范的消息契约和定义的服务契约进行一次通信,因此 SOAP 报文本身属于消息契约,同时该消息契约内要包括一个头对象 AuthenticationToken(使用 System.ServiceModel.MessageHeaderAttribute 属性修饰),另外这个 AuthenticationToken 对象还应该是一个数据契约(使用 DataContractAttribute 属性修饰)。定义 SOAP 头的消息契约类代码如下,这个实际是扩展自 Visual Studio 的 Services 引用向导生成的 partial 类。
public partial class serviceMethodRequest
{
[System.ServiceModel.MessageHeaderAttribute(Name = "AuthenticationToken", Namespace = "demoService")]
public DemoSoapHeader SoapHeader = new DemoSoapHeader();
}
需要注意的是其中 Namespace 参数与 WSDL 中定义的服务命名空间要对应,之前这个事就把我搞得头痛,还要感谢 Fiddler。再看看那个数据契约类代码,和上面是对应的。
[System.Runtime.Serialization.DataContractAttribute(Namespace = "demoService")]
[Serializable]
public class DemoSoapHeader
{
[System.Runtime.Serialization.DataMember()]
public string license = null;
}
剩下就是实例化客户端本地服务代理、实例化消息契约类、实例化并设置 SOAP 头数据契约类,调用等等正常走流程吧。
接下来说在 .NET 中通过 “传统”(是 2.0 时的经典方法吧,呵呵) Web 服务框架调用 XFire Web 服务。
其实这种方式在网上文档很多,这里也不想再重复。主要就是首先定义一个表式 SOAP 头的对象:
[System.Serializable]
[System.Xml.Serialization.XmlType(Namespace = "demoService")]
[System.Xml.Serialization.XmlRoot(Namespace = "demoService", IsNullable = false)]
public class AuthenticationToken : SoapHeader
{
public string license = null;
}
这里需要注意的就是类的名称 AuthenticationToken 就是 SOAP 报文中节点的名称,在这里和 WCF 中可配置的方式有些不同。然后扩展 Visual Studio 的 Web 引用向导生成的 partial 类,添加一个用来表示 SOAP 头中数据节点的成员对象:
public partial class DemoService
{
public AuthenticationToken SoapHeader = new AuthenticationToken();
}
最重要的是,还需要在 WebMethod 方法上添加属性,该方法位于 Visual Studio 的 Web 引用向导生成的服务代理类,指定 SOAP 头中携带对象元素所关联的成员变量:
[SoapHeader("SoapHeader")]
public OutEntBaseBean findEntBase([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] ParamClass in0)
{
// Invok code.
}
这里比较有趣的是,使用 WCF 服务模型来编写时,可以看到不需要修改 Visual Studio 引用向导生成的本地服务代理类中的代码,而使用 Web 服务模型时却需要在 WebMethod 上添加 SoapHeader 标签,这意味着使用后者时,只要在 Visual Studio 中刷新引用的服务时,都要重写添加所有更改过的代码,这个就比较郁闷了。
最后调用服务的方法相对使用 WCF 服务模型简单一些,实例化客户端本地服务代理、实例化并设置 SOAP 头对象、调用等等吧。
最后把 SOAP 报文也贴上来吧,首先是 WCF 服务模型生成的报文:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:AuthenticationToken xmlns:h="demoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:license>This is license.</h:license>
</h:AuthenticationToken>
</s:Header>
<s:Body>
</s:Body>
</s:Envelope>
接下来这个是 Web 服务模型生成的报文:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<AuthenticationToken xmlns="demoService">
<license>This is license.</license>
</AuthenticationToken>
</soap:Header>
<soap:Body>
</soap:Body>
</soap:Envelope>
上面的 Body 内容省略了。
就是以上这些了,实际这里涉及的内容是很简单的,但当真正做这件简单的事情时却也浪费了一些时间,在此做以记录备忘吧。欢迎大家一起讨论、提高。
注明:以上所有内容和代码,如与我有关项目或文档有相似之处纯属巧合。
// 2009.01.05 20:55 添加 ////
巧了,看来“头”的问题很重要啊,呵呵。
java axis调用带有soap头(soapheader)的.net webservice
// 2009.02.06 16:48 添加 ////
附件 MdmSvcCallee.zip 为备份目的所添加,请勿下载使用。
// 2009.03.07 13:30 添加 ////
作者:lzy.je
出处:http://lzy.iteye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分享到:
相关推荐
漫画作品与时间旅行题材
Spring Boot特点: 1、创建一个单独的Spring应用程序; 2、嵌入式Tomcat,无需部署WAR文件; 3、简化Maven配置; 4、自动配置Spring; 5、提供生产就绪功能,如指标,健康检查和外部配置; 6、绝对没有代码生成和XML的配置要求;第一章 绪 论 1 1.1背景及意义 1 1.2国内外研究概况 2 1.3 研究的内容 2 第二章 关键技术的研究 3 2.1 相关技术 3 2.2 Java技术 3 2.3 ECLIPSE 开发环境 4 2.4 Tomcat介绍 4 2.5 Spring Boot框架 5 第三章 系统分析 5 3.1 系统设计目标 6 3.2 系统可行性分析 6 3.3 系统功能分析和描述 7 3.4系统UML用例分析 8 3.4.1管理员用例 9 3.4.2用户用例 9 3.5系统流程分析 10 3.5.1添加信息流程 11 3.5.2操作流程 12 3.5.3删除信息流程 13 第四章 系统设计 14 4.1 系统体系结构 15 4.2 数据库设计原则 16 4.3 数据表 17 第五章 系统实现 18 5.1用户功能模块 18 5.2
内容概要:本文作为PyTorch的入门指南,首先介绍了PyTorch相较于TensorFlow的优势——动态计算图、自动微分和丰富API。接着讲解了环境搭建、PyTorch核心组件如张量(Tensor)、autograd模块以及神经网络的定义方式(如nn.Module),并且给出了详细的神经网络训练流程,包括前向传播、计算损失值、进行反向传播以计算梯度,最终调整权重参数。此外还简要提及了一些拓展资源以便进一步探索这个深度学习工具。 适用人群:初次接触深度学习技术的新学者和技术爱好者,有一定程序基础并希望通过PyTorch深入理解机器学习算法实现的人。 使用场景及目标:该文档有助于建立使用者对于深度学习及其具体实践有更加直观的理解,在完成本教程之后,读者应当能够在个人设备上正确部署Python环境,并依据指示独立创建自己的简易深度学习项目。 其他说明:文中所提及的所有示例均可被完整重现,同时官方提供的资料链接也可以方便有兴趣的人士对感兴趣之处继续挖掘,这不仅加深了对PyTorch本身的熟悉程度,也为未来的研究或者工程项目打下了良好的理论基础和实践经验。
古镇美食自驾游:舌尖上的历史韵味
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
漫画作品与神话传说融合
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
ADC推理软件AI程序
漫画作品与科幻元素融合
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
java-springboot+vue景区民宿预约系统实现源码(完整前后端+mysql+说明文档+LunW+PPT).zip
在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。
边境自驾游异国风情深度体验
在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。
,,CAD、DXF导图,自动进行位置路径规划,源码可进行简单功能添加实现设备所需功能,已经在冲孔机,点胶机上应用,性价比超高。 打孔机实测一分钟1400个孔 ,CAD、DXF导图;自动位置路径规划;源码功能添加;设备功能实现;冲孔机点胶机应用;高性价比。,CAD导图DXF,自动规划位置路径,实测打孔速度惊人!性价比超高冲孔机实现多功能定制
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
本地部署,LM Studio,可以让大家本地部署在自己家里的电脑deepseek,再也不用忍受网站上deepseek的服务器繁忙的烦恼