Изменение URL на клиенте веб-сервиса, сгенерированном с помощью wsimport - PullRequest
12 голосов
/ 25 августа 2010

Я пытаюсь написать модуль для приложения Java, которое обращается к WSDL-описанному веб-сервису.Исходный WSDL был загружен прямо из того, что я считаю веб-сервисом ASP.NET;URL-адрес службы заканчивается расширением .asmx, а при просмотре URL-адреса службы в браузере отображается ссылка, которую можно использовать для загрузки WSDL.

Для меня ключевым требованием является возможность отключения службыURL без перекомпиляции.Указанный мне URL-адрес, очевидно, является тестовым сервером, и я знаю, что в производственной среде мне дадут рабочий URL-адрес для использования.Я также хотел бы иметь возможность самостоятельно создать фиктивный сервер для тестирования и сохранить возможность указать новый URL-адрес в будущем без перекомпиляции, если служба перемещена.На самом деле, я бы хотел, чтобы установка нашего приложения позволяла создавать экземпляры нескольких экземпляров веб-сервиса по разным URL-адресам.

Но моя концепция, похоже, не соответствует тому, чтоинструмент wsimport делает для меня.После ответа f1sh здесь я сгенерировал код Java из загруженного WSDL с помощью этой команды:

wsimport -Xnocompile -keep -b binding.xml wsdlFile.wsdl

Я обнаружил, что сгенерированный код имеет жестко запрограммированную ссылку на мой загруженный файл wsdlFile.wsdl, который содержит URL службы.Наше приложение не будет работать таким образом, чтобы его можно было настроить путем редактирования файла WSDL во время выполнения.Мне нужно иметь код, который компилируется в мое приложение во время сборки и может иметь URL службы, установленный во время создания экземпляра.

Я не совсем уверен, почему WSDL даже нужно анализировать во время выполнения;Насколько я понимаю, WSDL предоставляет достаточно информации для генерации кода, который может получить доступ к веб-сервису, поэтому я не уверен, что он предоставляет сгенерированному коду, кроме URL-адреса службы, и я не уверен, почему URL-адрес службы не предоставляется вконструктор или настраивается с помощью метода в сгенерированном классе веб-сервиса.Я, должно быть, что-то упускаю.

Какова общая практика для этого сценария?Создает ли большинство людей код для каждого отдельного URL, который они собираются использовать?Код генерируется во время выполнения?Есть ли другой инструмент WSDL, который я могу использовать для создания клиентского кода с настраиваемым URL-адресом?

Ответы [ 2 ]

10 голосов
/ 25 августа 2010

Этот ответ ускользал от меня в течение нескольких дней, но каким-то образом процесс написания вопроса всегда фокусирует меня на поиске ответа, и еще пара веб-поисков указали на него:

http://www.fransvanbuul.net/?p=98

Похоже, что wsimport создал класс com.example.WebService, который расширяет javax.xml.ws.Service. Этот класс WebService имеет два конструктора. Конструктор без аргументов жестко запрограммирован с URL-адресом file: // для использования исходного WSDL, сгенерированного мной (Я полагаю, что если бы я указывал URL-адрес https: // в командной строке wsimport, это был бы жестко закодированный URL-адрес.) В качестве альтернативы я могу использовать конструктор с двумя аргументами и предоставить URL-адрес WSDL во время создания экземпляра! Этот подход требует от меня также предоставить в качестве второго аргумента объект javax.xml.namespace.QName, который я пока не понимаю.

Использование этого конструктора из двух аргументов, вероятно, решит мою проблему.

Кажется, что wsimport, который я использую из JDK 1.6, является частью пакета JAX-WS. JDK 1.6 в последних версиях содержит JAX-WS 2.1, а JAX-WS 2.2 решит проблемы, которые я поднимаю в этом вопросе.

Я буду рад принять любой ответ, который объясняет некоторые или все остальное в этой ситуации. Я до сих пор не понимаю, зачем нужен WSDL во время выполнения. На практике это помогло бы мне показать кому-то, как использовать конструктор с двумя аргументами или как сгенерировать мой код с JDK 1.6 и JAX-WS 2.2.

6 голосов
/ 25 августа 2010

Этот подход требует от меня также предоставить объект javax.xml.namespace.QName, который я пока не понимаю, в качестве второго аргумента.

Скопируйте один из вашего сгенерированного источника. QName - это XML квалифицированное имя - «уникальная» личность.

Я до сих пор не понимаю, зачем нужен WSDL во время выполнения.

Не могу сказать, что знаю точно, но WSDL - это в основном схема. Предоставляя его, я предполагаю, что вы дадите JAX-WS механизм для проверки ответа SOAP. Я не думаю, что привязки JAXB достаточно, чтобы сделать это.

Я всегда использую конструктор с двумя аргументами в сгенерированном сервисе для предоставления URL через метод ClassLoader.getResource для встраивания WSDL в мой jar. Как и в любой схеме, использование URL-адреса удаленной или файловой системы для этого глупо меньше оптимального.

См. этот вопрос о том, как установить конечную точку во время выполнения :

HelloService service = new HelloService();
Hello port = service.getHelloPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(
      BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
      "http://foo:8086/HelloWhatever");
String response = port.sayHello(name);
...