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 redivsent 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 redivsentation 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 redivsentation 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

本文来源:http://blog.csdn.net/helodd/archive/2007/06/28/1670190.aspx

Delphi Soap Header 的问题(来源于网络)相关推荐

  1. 了解下SOAP Header 元素

    SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换.可选的 SOAP Header 元素包含头部信息. SOAP Header 元素 可选的 SOAP Header 元素 ...

  2. Android基础总结+SQlite数据库【申明:来源于网络】

    Android基础总结+SQlite数据库[申明:来源于网络] 基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6 ...

  3. ************起步科技***********【申明:来源于网络】

    **起步科技*[申明:来源于网络] 地址:http://www.wex5.com/im/ 转载于:https://www.cnblogs.com/yearHeaven/p/9181283.html

  4. Android新手系列教程(申明:来源于网络)

    Android新手系列教程(申明:来源于网络) 地址:http://blog.csdn.net/column/details/androidcoder666.html 转载于:https://www. ...

  5. 软件项目开发计划书【申明:来源于网络】

    软件项目开发计划书[申明:来源于网络] 地址:http://jingyan.baidu.com/article/9f63fb91ab4da1c8400f0ea1.html 转载于:https://ww ...

  6. soap header身份认证 不带ns标签

    2019独角兽企业重金招聘Python工程师标准>>> 最近在做跟华为esdk服务通信的项目,esdk提供了两种方法,一种是soap,一种是native,关于native,因为是跟j ...

  7. J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式[申明:来源于网络]...

    J2EE进阶(十五)MyEclipse反向工程实现从数据库反向生成实体类之Hibernate方式[申明:来源于网络] 地址:http://blog.csdn.net/sunhuaqiang1/arti ...

  8. [silverlight]WCF和Web Service(ASMX)的soap header传输方法

    最近在研究silverlight的调用webservice或者WCF的安全验证问题,其中一个最基本的安全验证方法就是把用户名或者密码加入soap header里去,但是很多人都不知道怎么做,因为sil ...

  9. js读取解析JSON类型数据【申明:来源于网络】

    js读取解析JSON类型数据[申明:来源于网络] 地址:http://blog.csdn.net/sunhuaqiang1/article/details/47026841 转载于:https://w ...

最新文章

  1. 人工智能最佳学习实践
  2. xgb多线程成功运行记录
  3. 牛客网【每日一题】7月30日题目精讲—Xor Path
  4. sed中支持变量的处理方法
  5. opencv表面缺陷检测_机器视觉表面缺陷检测 光学元件瑕疵检测
  6. 参照 Vue 官方文档一步一步搭建 Vue
  7. Win8.1下COCOS2D-X 3.4环境搭建
  8. 【浙江省第16届省赛J:】Welcome Party(并查集+优先队列bfs遍历)
  9. VS2019如何打包程序
  10. torch的maximum与max以及导出onnx
  11. 区块链技术应用与安全发展
  12. 腾讯广告设计大赛初探
  13. 神经网络中的激活函数介绍
  14. use ida6.8 + windbg on win10
  15. 使用Sentinel LDK(Linux)对程序(*.so文件)加壳
  16. vb.netserialport数据接收不完整_北斗三号观测数据质量分析
  17. 五部搞定Android开发环境部署——费UC噶不过详细的Android开发环境搭建教程
  18. 机器学习KNN算法实践:预测城市空气质量
  19. 视频分享 | 你真的知道PCB走线与过孔的载流能力吗?
  20. 用Python实现全国二手房数据抓取+地图展示

热门文章

  1. 【Python3爬虫】下载酷狗音乐上的歌曲
  2. python的论文图表_如何利用Python绘制学术论文图表方法
  3. JS中数组随机排序实现(原地算法sort/shuffle算法)
  4. 2016最新H5面试题(及答案)
  5. MySQL 笔记 —— 时间函数、时间比较
  6. 3dsMax---点击渲染软件卡死
  7. ros安装并测试是否安装成功
  8. 财政直接支付和财政授权支付流程
  9. css环形文本,css制作环形文本
  10. 2022-2028年中国中低温余热发电行业市场发展潜力及投资前景分析报告