当前位置: 首页 > 知识库问答 >
问题:

用Delphi交换Web服务

岳俊晖
2023-03-14

我想使用Delphi XE6创建一个Exchange Web服务(EWS)客户端应用程序。

我正在使用带有wsdl的THttpRio组件。如何设置用户凭据?在其他语言中,相当于THttpRio组件的东西有一个凭据属性(示例)。但是Delphi组件缺少这个属性。

身份验证机制(除了模拟)不是ews wsdl的一部分。它是SOAP层固有的。

清单1:

procedure TForm1.Button1Click( Sender: TObject);
var
   lESB        : ExchangeServicePortType;
   request       : GetServiceConfiguration;
   Impersonation : ExchangeImpersonation;
   RequestVersion: RequestServerVersion;
   MailboxCulture1: MailboxCulture;
   GetServiceConfigurationResult: GetServiceConfigurationResponse;
   ServerVersion : ServerVersionInfo;
begin
lESB := HTTPRIO1 as ExchangeServicePortType;
request         := GetServiceConfiguration.Create;
request.RequestedConfiguration := ArrayOfServiceConfigurationType.Create( 'UnifiedMessagingConfiguration');
Impersonation   := ExchangeImpersonation.Create;
RequestVersion  := RequestServerVersion.Create;
MailboxCulture1 := MailboxCulture.Create;
GetServiceConfigurationResult:= GetServiceConfigurationResponse.Create;
ServerVersion                := ServerVersionInfo.Create;
try
lESB.GetServiceConfiguration(
  request, Impersonation, RequestVersion, MailboxCulture1,
  GetServiceConfigurationResult, ServerVersion)
finally
  request.Free;
  Impersonation.Free;
  RequestVersion.Free;
  MailboxCulture1.Free;
  GetServiceConfigurationResult.Free;
  ServerVersion.Free
  end
end;

上面的清单1显示了我迄今为止尝试过的一些示例代码。该函数的目的是获取有关服务器的版本信息。HTTPRIO1是一个具有默认属性的THTTPRIO组件,并连接到EWS的标准wsdl。这不起作用,因为未设置用户凭据。

如何设置用户凭据?

共有1个答案

虞裕
2023-03-14

经过大量的试验和错误,这是我想出的解决方案...

如果使用THTTPRio组件,则可以从通过代理服务器建立internet连接的角度,使用THHPRio的HTTPWebNode属性的用户名/密码对来标识用户的凭据。

如果使用THTTPReqResp组件,则相同的用户名/密码属性直接归该组件所有。

如果使用TIdHTTP,则可以使用与代理相关的属性。

如果要使用当前登录组件的凭据,并将密码显式传递到组件上,可以通过将THTTPRio和THTTPReqResp组件的用户名和密码属性留空来实现。代理信息将自动从系统注册表中获取。然而,这是不同的。该组件需要明确设置代理配置,包括internet用户的凭据。

我无法让标准的soap解决方案THTTPRio组件正常工作。问题是THTTPRio组件没有生成正确的请求信封形状。在没有详细说明的情况下,存在许多问题,比如应该放在主体中的元素,会出现在标题中,以及模式冲突。如果您可以让它(基于已发布的wsdl的THTTPRio)工作(但我对此表示怀疑),那么值得注意的是,需要对wsdl进行调整,以包含服务节点。出于安全原因,Microsoft故意将服务节点排除在外,但这是正确操作Delphi soap向导所必需的。

如果您的应用程序位于防火墙后面,并且必须与代理服务器协商,那么开发基于TIdHTTP的解决方案是不可能的。

最简单也是最好的解决方案是使用THTTPReqResp组件。你甚至不需要这个wisdl。您必须设计自己的xml请求信封,但有了Microsoft优秀的文档,显示了简单的信封,这项任务很难完成。

  1. EWS使用UTF-8,因此设置UseUTF8InHeader:=True
  2. Set InvokeOptions=[soIgnoreInvalidCerts,SOAutocheckAccessPointViaudi]
  3. 根据需要将URL设置为服务服务器URL
  4. 将SoapAction设置为http://schemas.microsoft.com/exchange/services/2006/messages
  5. 根据需要设置用户名和密码,或留空以使用登录用户的凭据
  6. EWS使用的是soap 1.1,而不是1.2,因此将wnoSOAP12从WebNodeOptions中排除
  7. 利用MSDN在线。这是一个极好的资源,有很多例子

Soap信封是遵循特定发布格式的XML文档,其中嵌入了您的请求数据。如何制作这些信封?

这里有两种可能的方法对我很有效:

  1. 使用模板软件设计模式。例如,我使用的组件与TPageProducer非常相似。源代码是您的基本模板,您可以使用标记替换来实现所需的结果。我的PageProducer版本可以定义可选片段,或者在一个模板中标记重复n次(每次迭代使用不同的数据)的片段

这里有两种可能的方法,你可以使用,但我建议不要。这并不是因为它们不起作用,而是因为这些技术太笨拙,需要太多的编码:

  1. 一部分一部分地手动将文档构造为字符串(或使用字符串生成器)
 类似资料:
  • 我是WebServices的新手。Im通过标记为“Transacted”的camel路由向cxfendpoint发送webservice请求,并得到响应。在同一事务路由中,next语句抛出一个异常,以便我的异常处理程序回滚该事务。 我可以在我的事务回滚中找到其他东西,除了我的webservice请求响应,因为它已经提交了。

  • 在 Web 服务器中 Web 应用程序的根目录是一个特定的路径。例如,一个catalog应用,可以位于 http://www.mycorp.com/catalog。以这个前缀开始的所有请求将被路由到代表 catalog 应用的 ServletContext 环境中。 servlet 容器能够制定Web应用程序自动生成的规则。例如,一个~user/映射可用于映射到一个基于/home /user/pu

  • Web服务是使用Web应用程序使用的Web协议访问的基于Web的功能。 Web服务开发有三个方面: 创建Web服务 创建代理 使用Web服务 创建Web服务 Web服务是一个Web应用程序,它基本上是一个由其他应用程序可以使用的方法组成的类。 它还遵循代码隐藏架构,例如ASP.NET网页,尽管它没有用户界面。 为了理解这个概念,让我们创建一个Web服务来提供股票价格信息。 客户可以根据股票代码查询

  • Web服务是一组基于Web的组件,有助于在应用程序或系统之间交换数据,这些数据还包括开放协议和标准。 它可以在网上发布,使用和发现。 Web服务有各种类型,如RWS(RESTfUL Web服务),WSDL,SOAP等等。 REST - 具象国家转移 一种远程访问协议,它将状态从客户端传输到服务器,可用于操作状态而不是调用远程过程。 没有定义任何特定的编码或结构以及返回有用错误消息的方法。 使用HT

  • EJB 3.0提供了将会话EJB公开为Web服务的选项。 @WebService注释用于将类标记为Web服务端点,@ WebMethod用于将方法作为Web方法公开给客户端。 @Stateless @WebService(serviceName="LibraryService") public class LibraryPersistentBean implements LibraryPersis

  • 大家好,我是微服务的架构新手,所以我有一个miscroservice,每个实体都链接到“用户”实体,但问题是“用户”实体在另一个微服务中,有什么解决方案吗? 如果我在同一个微服务中没有两个实体,我不知道在哪里使用@onetomany关系) 我无法将两个微服务组合在一起。 领域模型层呢?使用另一个微服务的数据是不是最好的解决方案? 提前感谢。