Delphi调用WebService踩坑流水账

最近要对接JAVA发布的WebServiC++e,发现发送的ISOAPHeader居然格式十分奇怪~,百度谷歌提供的方法居然是自己处理SOAPHeader,总感觉这种方法奇蠢无比,于是认真翻阅资料开始研究,总算摸到了一些思路,这里把过程流水账和解决办法提供给大家。

首先我们看需要的格式是这样的:

<SOAP-ENV:Envelopexmlns:SOAP-ENV="
SOAP-ENC="
XMLSchema-instance"xmlns:xsd="
kingdee.eas.base.btp.app.BTPManager/isPropOwner/parameter/promote">
<SOAP-ENV:Header>
<ns1:SessionId xmlns:ns1="http://login.webservice.bos.kingdee.com">
ada894c0-8223-41dc-b816-61eb67dc38bd
</ns1:SessionId>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:isPropOwnerxmlns:m="http://com.kingdee.eas.base.btp.app.BTPManager/
Service">
<m0:bosTypeStRing>BF76D8D1</m0:bosTypeString>
<m0:propName>id</m0:propName>
</m:isPropOwner>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

然而我们简单注册一个SOAPHeader,发送的格式却是这样的

<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:NS1="http://login.webservice.bos.kingdee.com"
xmlns:NS2="urn:WSSSCPersonFacade">
<NS1:SessionId xsi:type="NS2:SessionId">
<SessionId xsi:type="xsd:string">a8556725-3669-4f75-8101-24943c73203d</SessionId>
</NS1:SessionId>
</SOAP-ENV:Header>
<SOAP-ENV:Body
xmlns:NS3="http://webservice.app.bc.cp.eas.kingdee.com" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<NS3:getPersonList>
<currentOrgId xsi:type="xsd:string">00</currentOrgId>
<startIndex xsi:type="xsd:int">1</startIndex>
<fetchCount xsi:type="xsd:int">100</fetchCount>
</NS3:getPersonList>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Header中明显多了一些不该有的东西,这就坑爹了,难道真的要像一些文章里说的自己构造xml自己发送?总感觉这么做着实蠢,于是仔细谷歌翻看,突然看到一篇文章中提到了RegisterSerializeOptions(文章地址找不到了,sorry),作者遇到的是类似情况,在翻看delphi帮助手册后发现RegisterSerializeOptions可以控制SOAPHeader生成XML的样式,于是翻看帮助手册,发现了如下信息:

xoHolderClass The remotable object corresponds to a "holder" class. That is, the SOAP representation does not include a node for the class itself, but only 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).
xoAttributeOnLastMember Attributes of the remotable class are stored on the last member of the class that maps to an element node RATher than the node that corresponds to the class itself. This is necessary if a holder class has attributes.
xoInlineArrays If the remotable class contains class members that are array types, the encoding of those members omits the type name of the array types. This results in more efficient encoding of holder classes that represent array types.
xoLiteralParam The remotable class represents one of the two top-level nodes (the input or output value) of a document-literal encoding. The class is treated as a holder class if it is used as the direct input or output parameter of a function.
xoSimpleTypeWrapper The remotable class is a wrapper for a simple type such as a string or integer. The value that the class represents is expressed as a single published property of the remotable class.
xoOption5 - xoOptionI The remaining options are reserved for future use.

这是delphi帮助手册中的内容,经过多次尝试,最终确定了参数应该是RemClassRegistry.RegisterSerializeOptions(TypeInfo(SessionId), [xoSimpleTypeWrapper,xoLiteralParam]);

测试后打印的报文已经基本符合规定

<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:NS1="http://login.webservice.bos.kingdee.com">
<NS1:SessionId>a8556725-3669-4f75-8101-24943c73203d</NS1:SessionId>
</SOAP-ENV:Header>
<SOAP-ENV:Body
xmlns:NS2="http://webservice.app.bc.cp.eas.kingdee.com" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<NS2:getPersonList>
<currentOrgId xsi:type="xsd:string">00</currentOrgId>
<startIndex xsi:type="xsd:int">1</startIndex>
<fetchCount xsi:type="xsd:int">100</fetchCount>
</NS2:getPersonList>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

总的来说delphi还是没落了,很多问题搜索引擎都很难找到答案,不得不说对delphi开发者来说,环境越来越差了。

标签