【问题标题】:"Duplicate file name" for same WSDL namespace when using web-service from different sub-domains使用来自不同子域的 Web 服务时,相同 WSDL 命名空间的“重复文件名”
【发布时间】:2009-07-13 14:19:22
【问题描述】:

前言

我们正在向客户提供我们的服务 API。

每个客户都有自己的子域(例如 sergii.ourwebsite.com)和自己的 WSDL URL,它看起来像 http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl

此外,所有网站(当然包括 API)都使用相同的代码库。


问题

比如说,同一 CF 服务器上的两个应用程序。这很容易发生,因为一些客户网站托管在我们的服务器上。

都尝试使用自己的 API WSDL,比如:

http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl

问题来了。

当第二个网站尝试注册 web-service 时,CF 会抛出错误:

名称: https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl。 WSDL: https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl。 org.apache.axis.wsdl.toJava.DuplicateFileException: 重复的文件名: /opt/coldfusion8/stubs/WS1985941973/api/Bsapi.java。 提示:您可能已经映射了两个 具有相同元素的命名空间 name 为相同的包名。它是 建议您使用网络浏览器 检索和检查请求的 确保 WSDL 文档正确无误。 如果请求的 WSDL 文档不能 被检索或动态 产生,很可能是 目标 web 服务有编程 错误。

问题是它们都使用相同的 WSDL 命名空间,从 CFC 路径构建:

<wsdl:definitions targetNamespace="http://api">


当前解决方案

对我们来说唯一可行的解​​决方案是使用 CFC 别名,例如:

http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl

每个 CFC 都像这样扩展父级:

<cfcomponent output="false" extends="api.bsapi">
<!--- this component used to extend base api version 1.x --->
</cfcomponent>

它们产生不同的命名空间,可以毫无问题地使用——每个应用程序都有自己的命名空间:

<wsdl:definitions targetNamespace="http://v1n1.api">
<wsdl:definitions targetNamespace="http://v1n2.api">


这是一个非常愚蠢的解决方法,但它现在有效。


其他解决方案是使用单个 API 子域并通过某些密钥识别客户(我们已经将它们用于安全目的),但由于一些遗留代码,它对我们有严重的负面问题。


请注意,我不懂 Java,所以很多具体的建议对我来说不是很清楚。

Google 显示这个问题存在多年,但我找不到聪明的解决方案。

所以也许在这里?

【问题讨论】:

    标签: coldfusion wsdl stub


    【解决方案1】:

    我现在不能“将 WSDL 放在所有客户的公共 URL 上”,我已经解释了原因:因为我必须使用子域。如果您知道如何将 WSDL 放在一个 URL 上并向另一个 URL 发出服务请求,请告诉我。

    WSDL 只是描述 Web 服务的 XML 文档。您可以使用 CFML 编写(自定义)它。例如:

    http://subdomain.domain.com/api/wsdl.cfm?api=bsapi&amp;customer=subdomain

    然后只需复制 CF 生成的 WSDL,并将其用作自定义 WSDL 页面的模板。替换特定于子域​​的 WSDL 部分并返回 XML 文档。注意空格(可能参见CFSilentCFSetting),并考虑使用CFHeader 将mime 类型设置为“text/xml”。

    【讨论】:

      【解决方案2】:

      是否所有客户都使用相同的 WSDL?然后将 WSDL 放置在所有客户的公共 URL 中。

      我还认为您需要确切了解错误消息的含义。我看不出它与正在使用的 URL 有什么关系。如果它提到了另一个客户的 URL,我会理解的。


      部分原因可能是我对 CF 的工作原理缺乏了解。特别是,当两个客户这样做时会触发问题的“注册 Web 服务”是什么?

      您是否意识到 WSDL 中 &lt;soap:address/&gt; 元素中的 URL 只是一个提示?在许多客户端中,它可以被覆盖。在 .NET 客户端中,只需设置代理类的 Url 属性。这应该允许您在一个位置拥有一个单一的 WSDL,并且让您的客户每个都引用正确的子域,假设有某种方法可以将这些信息传达给他们。例如,如果有一种方法可以让您知道哪个客户正在拨打电话,那么也许您可以在一个 URL 上接收呼叫,然后重定向到正确的 URL,或者使用 SOAP 路由基础结构路由到正确的 URL。

      我希望您不会将命名空间从一个客户更改为另一个客户。命名空间与 URL 无关,即使它们恰好看起来像 URL。

      【讨论】:

      • 我现在不能“将 WSDL 放在所有客户的公共 URL 上”,我已经解释了原因:因为我必须使用子域。如果您知道将 WSDL 放在一个 URL 并向另一个 URL 发出服务请求的方法——请告诉我。
      • “找出错误消息的确切含义”——这就是创建问题的原因,对吧?它没有说明 URL,但是链 URL => 命名空间 => 存根的问题非常明显。
      • 关于
        的提示很有用,谢谢。将尝试将其与亚当的命题结合起来。
      【解决方案3】:

      cfcomponent 标签有一个命名空间属性。您应该能够使用它以及 cgi.host_name (?我在家,没有文档)来指定与正在查询的子域匹配的命名空间。

      类似:

      <cfcomponent namespace="http://#cgi.host_name#/api/v1n1/bsapi.cfc">
      

      【讨论】:

      • 但是如果结果证明所有 WSDL 都是一样的,那就不正确了。
      • 这是个好主意,我也想过。但据我了解,cfcomponent 标签属性中不能使用动态值。我错了吗?
      • 我没有尝试在那里使用动态值。试试看。如果这不起作用,您可能必须将服务统一在一个 URL 上,这也将解决 John 的反对意见。
      【解决方案4】:

      当尝试通过位于同一 localhost(但在不同文件夹中)的测试脚本从 localhost 进行 CFINVOKE 网络服务时,已捕获此错误消息。对我来说听起来“很糟糕”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-03
        • 1970-01-01
        • 2014-05-03
        • 2010-10-05
        • 2012-03-07
        • 2013-03-14
        • 2012-01-08
        • 1970-01-01
        相关资源
        最近更新 更多