Delphi的SOAP Header问题

Delphi实现WebService带身份认证的数据传输 在WebService中,用户身份认证信息可以在客户端通过soap头(soapheader)进行传送。在WebService服务端的编写中,需要对soap头进行处理,这个处理过程就是提取SoapHeader中的用户认证信息进行验证。下面就来看看在Delphi中这个身份认证是如何实 阅读详情
Delphi的SOAP Header问题

1.Delphi给了一个SOAP Header的示例
以下内容为程序代码:

<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:BankAccountIntf">
   <NS1:AuthHeader xsi:type="NS1:AuthHeader">
       <AccNumber xsi:type="xsd:int">4</AccNumber>
       <TimeStamp xsi:type="xsd:dateTime">2005-01-06T15:01:26.531Z</TimeStamp>
   </NS1:AuthHeader>
</SOAP-ENV:Header>


实现方法是:
1.先定义一个TSOAPHeader的继承类,要在SOAP包中出现的字段以property方式出现
以下内容为程序代码:

 AuthHeader = class(TSOAPHeader)
 private
   FAccNumber: Integer;
   FTimeStamp: TXSDateTime;
 public
   destructor Destroy; override;  //用于释放FTimeStamp,别无它用
 published
   property AccNumber: Integer read FAccNumber write FAccNumber;
   property TimeStamp: TXSDateTime read FTimeStamp write FTimeStamp;
 end;

2.在initialization中注册
以下内容为程序代码:

 InvRegistry.RegisterHeaderClass(TypeInfo(IBankAccount), AuthHeader, 'AuthHeader', 'urn:BankAccountIntf');
 RemClassRegistry.RegisterXSClass(AuthHeader, 'urn:BankAccountIntf', 'AuthHeader');

3.使用:
以下内容为程序代码:

var
 H: AuthHeader;
 svc: IBankAccount;
begin
 svc := HTTPRIO1 as IBankAccount;

 H := AuthHeader.Create;
 try
   H.AccNumber := FAuthKey;
   H.TimeStamp := DateTimeToXSDateTime(FTimeStamp, True);
   if UseHeader then
    (svc as ISOAPHeaders).send(H);
   svc.some_method(...)
 except...


2. 我的要求和问题
对于我的程序,服务器要求的Header是这样
以下内容为程序代码:

<SOAP-ENV:Header>
 <Username xsi:type="xsd:string" SOAP-ENC:root="1">BigLuo</Username>
 <Password xsi:type="xsd:string" SOAP-ENC:root="1">111</Password>
</SOAP-ENV:Header>

与上面的不同是Header下直接是两个元素,没有一个NS1:AuthHeader的外包层

仔细查看了一下Delphi的帮助,在Defining and using SOAP headers一节淘到如下一段
以下为引用:

Handling scalar-type headers

Some Web Services define and use headers that are simple types (such as an integer or string) rather than a complex structure that corresponds to a remotable type. However, Delphi's support for SOAP headers requires that you use a TSOAPHeader descendant to represent header types. You can define header classes for simple types by treating the TSOAPHeader class as a holder class. That is, the TSOAPHeader descendant has a single published property, which is the type of the actual header. To signal that the SOAP representation does not need to include a node for the TSOAPHeader descendant, call the remotable type registry's RegisterSerializeOptions method (after registering the header type) and give your header type an option of xoSimpleTypeWrapper.



从最后一句看,我只要这样定义:
以下内容为程序代码:

 HdrUsername = class(TSOAPHeader)
 private
   FUsername: String;
 published
   property Username: String read FUsername write FUsername;
 end;

然后按如下方式注册
以下内容为程序代码:

   InvRegistry.RegisterHeaderClass(TypeInfo(ezMsgServer), HdrUsername, 'Username', ');
   RemClassRegistry.RegisterSerializeOptions(TypeInfo(HdrUsername), [xoSimpleTypeWrapper]);

(Password一项也类似处理)
应该就可以了。

但运行一下发现文档里面说的根本就不对,而是这样:
以下内容为程序代码:

<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:ezMsgServiceWrapper">        <NS1:HdrUsername xsi:type="NS1:HdrUsername">
               <Username xsi:type="xsd:string">y19451</Username>
       </NS1:HdrUsername>
       <NS1:HdrPassword xsi:type="NS1:Password">
               <Password xsi:type="xsd:string">mypass</Password>
       </NS1:HdrPassword>
</SOAP-ENV:Header>

看样子xoSimpleTypeWrapper根本没有任何作用(不加那一句也是这个结果)

3. 问题的解决
在帮助文件里面来回折腾了半天,看到RegisterSerializeOptions的帮助里提到这样一个选项
以下为引用:

xoHolderClass
The remotable object corresponds to a "holder" class. That is, the SOAP representation does not include a node for the class itself, just for its members. This is used when a type that would otherwise not require a remotable class uses a feature only available on remotable classes (such as attributes).



这个选项倒好像跟我的需求比较接近哦,试试!
结果又是失望。“希望,失望,希望,失望”,麦兜抱怨到。

在google上搜索了半天没有发现什么有用的结果,在无望之余回来又来看Delphi提供的例子,注意到它的例子中将AuthHeader这个类注册了一下:
       RemClassRegistry.RegisterXSClass(AuthHeader, 'urn:BankAccountIntf', 'AuthHeader');
对啊,这个类应该在Remote Class Registry里面注册,于是加上HdrUsername和HdrPassword的注册语句, 再试,搞定!

总结一下:
帮助里面说的应该是纯常量作为Header的情况,对于我这种<username>...</username><password>...</password>的情况,应该按如下方式处理:
1. 按上面所说,声明HdrUsername和HdrPassword
2. 在initialization时按如下方式注册
[/code]
 nvRegistry.RegisterHeaderClass(TypeInfo(ezMsgServer), HdrUsername, 'Username', ');
 RemClassRegistry.RegisterXSClass(HdrUsername, ', 'Username', 'Username');
 RemClassRegistry.RegisterSerializeOptions(TypeInfo(HdrUsername), [xoHolderClass]);

 InvRegistry.RegisterHeaderClass(TypeInfo(ezMsgServer), HdrPassword, 'Password', ');
 RemClassRegistry.RegisterXSClass(HdrPassword, ', 'Password', 'Password');
 RemClassRegistry.RegisterSerializeOptions(HdrPassword, [xoHolderClass]);
[/code]

其实这样也可以(而且简单一点):
1.  将Username和Password声明在一个Header内
以下内容为程序代码:

TezMsgHdr = class(TSOAPHeader)
 private
   FUsername: String;
   FPassword: String;
 published
   property Username: String read FUsername write FUsername;
   property Password: String read FPassword write FPassword;
 end;

2.将TMsgHdr注册:
以下内容为程序代码:

 InvRegistry.RegisterHeaderClass(TypeInfo(ezMsgServer), TezMsgHdr, 'Username', ', hmtRequest);
 RemClassRegistry.RegisterXSInfo(TypeInfo(TezMsgHdr), ', 'Username', 'Username');
 RemClassRegistry.RegisterSerializeOptions(TypeInfo(TezMsgHdr), [xoSimpleTypeWrapper, xoHolderClass]);


4. 其他
细心的话,可以注意到后面一种方法里面多了一个xoSimpleTypeWrapper选项。其实对于后一种方法的复杂类TezMsgHdr, 这个选项是无效的,但对于前一种,就有些不同了(正如其名称所表明的那样,只有真正是SimpleType才有作用):

a. 如果只对HdrUsername加xoSimpleTypeWrapper选项:
以下内容为程序代码:

<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:ezMsgServiceWrapper" xsi:type="NS1:Password">y19451<Password xsi:type="xsd:string">Password</Password></SOAP-ENV:Header>

可以注意到Username元素不见了,只能见到其值y19451赤裸地出现,而Password一项正常

b.如果只对HdrPassword加xoSimpleTypeWrapper选项:
运行时会出现"Element does not contain a single text node"这样的错误。我估计SOAP Header如下,Password的出现导致了这不是一个合法的XML
以下内容为程序代码:

<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:ezMsgServiceWrapper" xsi:type="NS1:Password"><Username xsi:type="xsd:string>y19451</Username>Password</SOAP-ENV:Header>


c.如果两者都加xoSimpleTypeWrapper选项,结果会是怎样呢?
以下内容为程序代码:

 <SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:ezMsgServiceWrapper" xsi:type="NS1:Password">Password</SOAP-ENV:Header>

居然Username都不见了


 引自 元聊的技术 http://www.blogone.net/user20/bamanzi/blog/5610658.html
Delphi WebService 利用 TSOAPAttachment 传文件的例子代码 WebService 程序利用 TSOAPAttachment 来上传或下载文件 立即下载

相关推荐

魔百和CM211-1刷Armbian全流程:从安卓盒子到Linux服务器的完美变身

本文详细介绍了如何将魔百和CM211-1机顶盒刷入Armbian系统,实现从安卓盒子到Linux服务器的完美变身。涵盖硬件兼容性验证、固件选择、刷机流程、系统优化及常见问题解决,特别适合技术爱好者低成本搭建家庭NAS或开发环境。

weixin_30329623的博客 238

【编程题】Single Element in a Sorted Array

/**************** 思想:    抑或操作 复杂度:     O(n) ************************/ int singleNonDuplicate(vector& nums) { int size = nums.size(); int ans = nums[0]; for (int ii = 1; ii { ans ^= nums[ii

魔幻世界 493

Ubuntu服务器通过IPV6端口转发搭建幻兽帕鲁私服实战

本文详细介绍了在Ubuntu服务器上通过IPV6端口转发搭建幻兽帕鲁私服的完整教程。针对只有公网IPV6地址的服务器环境,提供了从硬件检查、端口转发工具配置到游戏服务器安装的全流程解决方案,帮助玩家轻松实现多人联机游戏体验。

weixin_30652491的博客 490

delphi webserver soap头(soap header)信息传送

在做一个webserver 接口的时候,需要在soap header传送登录后的SessionId,通常delphi生成接口后传送的XML里是不会有包括header数据信息的,这就只能是写代码增加上去。 那么,首先我们需要先自行定义一个类: const IS_TEXT = $0020; {一个常量,也很重要} //这个定义了 Header信息基础类 TSessionIdHeader = class(TSOAPHeader) private FValue: string;

tanqth的专栏 1万+

机械臂抓取前言

机械臂相关的笔记

weixin_64037619的博客 3908

单细胞转录组上游分析完整流程(超详细)

本指南详细介绍单细胞转录组数据分析流程,从10xGenomics平台数据出发,使用CellRanger工具完成从原始FASTQ文件到基因表达矩阵的全过程。内容涵盖:1) 环境准备与参考基因组获取;2) 测试数据下载;3) 数据质量检测方法;4) CellRanger核心流程详解;5) 结果解读;6) 下游分析衔接。同时提供开源替代方案kallisto|bustools的使用说明,并解答常见问题。适合单细胞转录组分析初学者快速掌握标准分析流程。

Rita_rr的博客 1156

Delphi Soap Header 的问题(来源于网络)

Delphi的SOAP Header问题1.Delphi给了一个SOAP Header的示例以下内容为程序代码:          4       2005-01-06T15:01:26.531Z   实现方法是:1.先定义一个TSOAPHeader的继承类,要在SOAP包中出现的字段以property方式出现

PenGHNet的专栏 2762

单相PWM整流器四象限运行原理

简述单相PWM整流器四象限运行原理。

m0_75208156的博客 8298

Delphi WebService 使用 HTTP Header 管理 Session

使用 Delphi 的 WebBroker 框架可以开发标准的 Web Server 程序。使用 Delphi 的 SOAP 框架,可以开发支持 SOAP 标准的 WebService 服务端程序。此框架建立的 WebBroker 框架之上。使用 Delphi 可以开发客户端程序,去调用 WebService 服务器提供的 SOAP 函数。同时也可以去调用 WebBroker 开发的 Web Server 提供的 RESTfull 的 URL 接口。

pcplayer的博客 275

不经意传输(OT)协议 - Mike Rosulek教授课堂笔记

OT扩展协议-IKNP

qq_43569221的博客 1850

23种设计模式-代理(Proxy)设计模式

软考中级-软件设计师 代理设计模式

片言可决讼,半纸能缚龙 1783

如何在 SOAP 接口调用的 Http header 中增加字段

在 Delphi 中添加 SOAP Header 就不用说了,请参考 Delphi 自带示例,位于 Demos/WebServices/SOAPHeaders 目录下。添加 Http header 字段示例如下。示例 WSDL 文件描述如下:  SampleServiceSoap = class(IInvokable)  [{08323867-2307-4569-8405-4E575CC

Alan的专栏 5077

MATLAB与ROS联合仿真——实例程序搭建思路

MATLAB与ROS联合仿真——实例程序搭建思路

慕羽★的博客 5228

Delphi下使用Webservice的用户验证

Delphi下使用Webservice的用户验证       在Delphi下使用Webservice时,通常我们使用Delphi自带的功能对webservice接口生成调用pas,其中对用户名密码的设置是通过对THTTPRIO对象的HTTPWebNode属性进行设置, RIO := THTTPRIO.Create(nil);   try     RIO.WSDLLocation

pmj888666的专栏 950

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Delphi采用THTTPReqResp处理websever服务用例

Delphi采用THTTPReqResp处理websever服务用例 1、先定义这个传入体 const SOAPSTR = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:good="http://goodwillcis.com">'+ ' <soapenv:Header>'+ ' <good:JiaheSecurity>

Amelie_W的博客 1200

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Delphi中WebService服务

Delphi开发和调用的webservice 在用delphi编写webservice时遇到的第一问题就是如何编写,怎么写?上网查了一下,内容还是听不少的,当然通过多方资料的比较,了解到通过file--new----other----webservice可以建立并测试webservice,但是我的delphi中却没有这个选择,于是很迷茫,问了一下“大牛”程序员才知道,是因为我的vcl自带的包...

weixin_34005042的博客 150

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Delphi 调用带包头的 WebService

代码如下: unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, InvokeRegistry, Rio, SOAPHTTPClient; type TForm1 = class(TF...

weixin_30692143的博客 240

RESTful Webservice 和 SOAP Webserivce 对比

接口抽象 RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力,而不同的是,SOAP 应用都通过定义自己个性化的接口方法来抽象 Web 服务,这更像我们经常谈到的 RPC。例如本例中的 getUserList 与 getUserByName 方法。 RESTful Web 服务使用标准的 HTTP 方

shadow_zed的博客 375

XE10 Android SOAP请求遭遇到Insufficient RTTI available to support this operation异常

XE10 Android 使用 SOAP请求服务器数据, 请求多次后, 遭遇到Insufficient RTTI available to support this operation异常的解决方法

ssxbxk的博客 1065

WebService基于SoapHeader实现安全认证

1.首先要自定义SoapHeader,须继承System.Web.Services.Protocols.SoapHeader 。 using System; using System.Collections.Generic; using System.Web; /// ///自定义的SoapHeader /// public class MySoapHeader : System.Web.

我的地盘 914
上一篇: VS.NET检测到的Web服务器运行的不是Asp.net 1.1版
下一篇: 直接将数据导出到Excel文件,直接操作文件没有使用Variant
helodd
博客等级 码龄24年 40粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值