«Повторяющееся имя файла» для одного и того же пространства имен WSDL при использовании веб-службы из разных поддоменов - PullRequest
1 голос
/ 13 июля 2009

Введение

Мы предоставляем клиентам наш сервис API.

У каждого клиента есть собственный поддомен (например, sergii.ourwebsite.com) и собственный URL-адрес WSDL, который выглядит как 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

А вот и проблемы.

Когда второй сайт пытается зарегистрировать веб-сервис, 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. Подсказка: вы могли нанести на карту два пространства имен с элементами того же имя для того же имени пакета. это рекомендуется использовать веб-браузер получить и изучить запрошенный WSDL документ, чтобы убедиться, что это правильно. Если запрошенный документ WSDL не может быть извлеченным или динамически вероятно, что целевой веб-сервис имеет программирование ошибки.

Проблема в том, что они оба используют одно и то же пространство имен 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 показывает, что эта проблема существует годами, но я не могу найти разумное решение.

Так может здесь?

Ответы [ 4 ]

2 голосов
/ 14 июля 2009

Пока я не могу "разместить WSDL на общем URL-адресе для всех клиентов", и я объяснил почему: потому что я должен использовать субдомены. Если вы знаете, как разместить WSDL на одном URL-адресе и отправить запрос на обслуживание другому - скажите, пожалуйста.

WSDL - это просто документ XML, описывающий веб-сервис. Вы можете написать (настроить) его с помощью CFML. Например:

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

Затем просто скопируйте WSDL, сгенерированный CF, и используйте его в качестве шаблона для своей пользовательской страницы WSDL. Замените части WSDL, которые зависят от субдомена, и верните XML-документ. Помните о пробелах (возможно, смотрите CFSilent , CFSetting ) и подумайте об использовании CFHeader , чтобы установить тип mime для "text / xml".

1 голос
/ 13 июля 2009

Все ли клиенты используют один и тот же WSDL? Затем разместите WSDL по общему URL для всех клиентов.

Я также думаю, что вам нужно выяснить, что именно означает сообщение об ошибке. Я не вижу, какое отношение это имеет к используемому URL. Если бы он упомянул URL другого клиента, я бы понял.


Частично это может быть из-за моего непонимания того, как работает CF. В частности, что это за «регистрация веб-сервисов», которая вызывает проблему, когда это делают два клиента?

Понимаете ли вы, что URL-адрес в элементе <soap:address/> в WSDL является лишь подсказкой? У многих клиентов это может быть переопределено. В клиенте .NET просто установите свойство Url прокси-класса. Это должно позволить вам иметь один WSDL в одном месте, и при этом ваши клиенты каждый должны ссылаться на соответствующий поддомен, при условии, что есть какой-то способ донести эту информацию до них. Например, если у вас есть способ узнать, какой клиент совершает вызов, то, возможно, вы могли бы получать вызовы по одному URL-адресу и затем перенаправлять на правильный URL-адрес или использовать инфраструктуру маршрутизации SOAP для маршрутизации на правильный.

Я надеюсь, что вы не меняете пространства имен от одного клиента к другому. Пространства имен не имеют ничего общего с URL-адресами, даже если они выглядят как URL-адреса.

0 голосов
/ 30 августа 2010

Получено это сообщение об ошибке при попытке выполнить веб-службу CFINVOKE с локального хоста с помощью тестового сценария, расположенного на том же локальном хосте (но в другой папке). Звучит "баггино" для меня.

0 голосов
/ 13 июля 2009

Для тега cfcomponent существует атрибут пространства имен. Вы должны иметь возможность использовать это вместе с cgi.host_name (? Я дома, без документов), чтобы указать пространство имен, которое соответствует запрашиваемому поддомену.

Что-то вроде:

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