我正在尝试使用基于Java的webservice并有soap请求:
<?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:Body xmlns:NS1="http://something/">
<NS1:getRequest id="1">
<sessionId xsi:type="xsd:string"></sessionId>
<reportType xsi:type="NS1:reportType">ALL</reportType>
<xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
<xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
</NS1:getRequest>
<parameters href="#1" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
它不起作用,因为webservice不会将日期识别为参数。当我改变
<xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
<xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
到
<dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
<dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
一切正常,但Delphi(没有Delphi源代码更改)不允许更改生成的XML,它只有一些选项。是否可以设置转换选项,因此TSXDateTime
转换为<dateFrom
,而不是<xsd:dateFrom
代码?你遇到了这个问题吗?
答案 0 :(得分:0)
您可以在反序列化之前拦截XML,并使用stringreplace编辑您的内容。您需要挂钩其中一个RIO事件。
更新:点击此处: HTTPRIO1AfterExecute(const MethodName:string; SOAPResponse:TStream);
SOAPResponse是一个流,不像字符串那样易于操作,但它绝对是可修改的。我明天下午可以发布一些示例代码。
编辑:OnDfterExecute出现在D2007及更高版本中,您可以使用D2007 SOAP源在D2005中使用它。关于D7不确定!你可能是SOL。
编辑:在D7上,您可能会破解代码以提供您自己的OnAfterExecute事件。即修改rio.pas以包含处理程序。此外,使用流对象时常见的错误是在完成后无法将位置重置为0.
编辑:你也可以在BeforeExecute中编辑请求,尽管可能没有使用Delphi7代码。在D2010(我现在在我面前),SOAPRequest是一个流。在D2007(我曾经广泛使用,但实际上在D2005上使用D2007代码),我相信它是一个字符串。在我的D2005 / 2007项目中,我们使用OnBeforeExecute中的一系列StringReplace()语句广泛编辑请求。
答案 1 :(得分:0)
我找到了解决方案。我继承自THttpRIO,因为DoBeforeExecute
是virtual
,我改变了它的实现(DoBeforeExecute来自Delphi 2007,允许在OnBeforeExecute
中更改xml)。然后我将自动生成的WSDL单元改为使用TMyHttpRIO:
unit MyHttpRIO;
interface
uses
RIO, Classes, SOAPHTTPClient;
type
TMyHttpRIO = class(THttpRIO)
procedure DoBeforeExecute(const MethodName: string; Request: TStream); override;
private
end;
implementation
{ TMyHttpRIO }
procedure TMyHttpRIO.DoBeforeExecute(const MethodName: string;
Request: TStream);
var
StrStrm: TStringStream;
SavedRequest: WideString;
ReqWideStr: WideString;
begin
if Assigned(OnBeforeExecute) then
begin
{ Ideally we would change the signature of this event to take a Stream.
The change to stream was necessary for attachment and encoding support.
And it makes the event consistent.... However, for the sake of
backward compatibility.... }
StrStrm := TStringStream.Create('');
try
StrStrm.CopyFrom(Request, 0);
Request.Position := 0;
ReqWideStr := UTF8Decode(StrStrm.DataString);
SavedRequest := ReqWideStr;
OnBeforeExecute(MethodName, ReqWideStr);
finally
StrStrm.Free;
end;
if (Length(SavedRequest) <> Length(ReqWideStr)) or (SavedRequest <> ReqWideStr) then
begin
// Copy changes made to ReqWideStr in the event back to the Request stream
StrStrm := TStringStream.Create(string(ReqWideStr));
try
StrStrm.Position := 0;
Request.Size := 0;
Request.CopyFrom(StrStrm, 0);
Request.Position := 0;
finally
StrStrm.Free;
end;
end;
end;
end;
end.