Как стать автором
Обновить

Комментарии 30

Web-сервисы на Java

1. Класс сервиса:

package com.horstmann.corejava;
import java.util.*;
import javax.jws.*;
/**
 * This class is the implementation for a Warehouse web service
 * @version 1.0 2007-10-09
 * @author Cay Horstmann
 */
@WebService
public class Warehouse
{
   public Warehouse() 
   {
      prices = new HashMap<String, Double>();
      prices.put("Blackwell Toaster", 24.95);
      prices.put("ZapXpress Microwave Oven", 49.95);
   }

   public double getPrice(@WebParam(name="description") String description)
   {
      Double price = prices.get(description);
      return price == null ? 0 : price;
   }
   private Map<String, Double> prices;
}


2. Класс сервера:

package com.horstmann.corejava;
import javax.xml.ws.*;
public class WarehouseServer
{
   public static void main(String[] args)
   {
      Endpoint.publish("http://localhost:8080/WebServices/warehouse", new Warehouse());
   }
}


3. Класс клиента:

import java.rmi.*;
import javax.naming.*;
import com.horstmann.corejava.server.*;
/**
 * The client for the warehouse program.
 * @version 1.0 2007-10-09
 * @author Cay Horstmann
 */
public class WarehouseClient
{
   public static void main(String[] args) throws NamingException, RemoteException
   {
      WarehouseService service = new WarehouseService();      
      Warehouse port = service.getPort(Warehouse.class);
      String descr = "Blackwell Toaster";
      double price = port.getPrice(descr);
      System.out.println(descr + ": " + price);
   }
}


Источник: archive.williamspublishing.com/cgi-bin/materials.cgi?isbn=978-5-8459-1482-8

По-сути, ничего сложного нет.
Но это не все файлы.
Ещё кучу «заглушек» надо наштамповать с помощью wsgen и wsimport (входят в поставку JDK).

Среды программирования NetBeans и Eclipse это делают «на автомате», но после их работы код получается сверх-избыточным.
В приведенном примере используется динамическая генерация стабов в рантайме. Но в большинстве случаев конечно используется статическая генерация со всеми вытекающими заглушками.
Пробовал откомпилировать и запустить. Но что-то не ощутил динамической генерации стабов. Надо руками всё делать.
Какая версия JDK? или JEE?
Работает начиная с 1.6 и 5 соответственно.
А есть ли реализации WSDL (версия 1.x) клиентов (для PHP, Java) которые нормально понимают HTTP binding (REST)? Большинство с чем сталкивался нормально парсят только SOAP binding.
а это не оно, случаем? wso2.org/projects/wsf/php/features там много занятных либ есть очень, рекомендую посмотреть
Пакеты javax.ws.rs, javax.ws.rs.core, javax.ws.rs.ext, имплементирующие JAX-RS API (JSR-311), входят в Sun JRE 1.6.

Примеры, использующие JAX-RS API, можно посмотреть в NetBeans 6.5.
Ошибся. Библиотека JAX-RS API поставляется вместе с NetBeans6.5, в JRE/JDK нету этого API.
понял, увы, далеко не все, но было очень интересно.
надо разбираться.
Как по мне, приведенные в статье примеры далеко не для начинающих. Возможно из-за использования фреймворков.
WSDL, сгенерированный Zend'ом для более-менее развесистого сервера, просто неподъемен. Вы забыли, что SOAP еще обеспечивает более строгую типизацию и сильно удобен для сообщения между сервисами.
Спасибо, обязательно внесу исправления в текст. Вы не против?
Разумеется не против
Хм. Использование фреймворков в этой статье делает SOAP и REST концептуально неразличимыми для читателя.
Увы, это так, и я об этом сам сказал и в статье. Возможно дополню чуть позже другим примером именно для REST. Прямо сейчас занят другой статьей не хочу отвлекаться :)
> mikhailstadnik.com/ctws/currency.wsdl
А для WSDL файлика разве не должен отдаваться content-type application/xml или подобный?
А то, боюсь, не все клиенты смогут нормально его прочитать…
Ну в данном случае это больше проблема настройки веб-сервера, так как отдается просто статичный файл. Тем не менее имея полный доступ к серверу — поправил :) спасибо
Zend_Rest выглядит действительно как RPC.
По моему REST URLдолжен выглядеть так: /rates/EUR-USD/2008-12-10/
* вызов просто /rates/ возвращает все доступные пары валют
* вызов /rates/EUR-USD/ возвращает все значения пары EUR-USD

А я не понял главного — для чего нужны все эти SOAP и XML-RPC :)
Уж не судите строго, а объясните подробнее, если не сложно.

Вот возьмём «склонятор» яндекса nano.yandex.ru/project/inflect/
Почему бы просто не сделать вот так

file_get_contents(«export.yandex.ru/inflect.xml?name=...»);

И потом разобрать пришедший xml?

Вот будет выглядеть реализация этого примера с помощью SOAP?
Посмотрите с другой стороны — предположите, что вам нужно сделать «склонятор» :)
Кроме того, современные инструменты позволяют не разбирать XML самому, если уж речь идет о клиенте.
Смотрю, но ничего не вижу :)
Я представляю себе задачу как простое получение параметра, формирование для него результата и его вывод в виде xml. Чтобы собрать и разобрать xml есть SimpleXML и т.п.

Т.е. я вижу тут xml как главного посредника, а зачем всё остальное… не мойму :)
По сути вашего вопроса:
XML действительно посредник, но сам по себе XML — это формат без какой либо определенной структуры. А это значит что вам следует ее определять самому. И донести это до всех, кто захочет с вашей структурой работать.
А SOAP — это стандарт известный всем :) И многие языки УЖЕ имеют инструментарий по сборке и разбору структуры его XML (что в примерах к статье и показано).

А сам принцип о котором вы говорите — больше из концепции REST, которая именно так все и упрощает (получил параметр — отдал ресурс). В рамках веб — это всем понятно.

А сам SOAP больше завязан на теории ООП и удаленного вызова процедур (манипулирование с удаленными объектами, неизвестно на чем написанными).
Спасибо, последний абзац немного прояснил ситуацию )
SOAP по сути это стандарт, которого нужно придерживаться для того, чтобы Ваш сервис могли использовать клиенты, написаные на совершенно разных языках программирования и под различные платформы. Над SOAP есть множество стандартных настроек для решения типичных задач (authentication/reliable messaging/transactions/security tokens/etc), использование которых сделает ваш сервис совместимым с большим количеством клиентов.
В данном обзоре пропущена важная часть, связаная с веб-сервисами. Это WS-I Basic Profile — набор рекоммендаций и стандартов к SOAP, WSDL, UDDI для девелоперов веб-сервисов, предназначеная для того, чтобы увеличить interoperability(возможность взаимодействия\совместимость?) между приложениями.
Ну вообщем SOAP это стандартизированый XML c целым набором технологий, основная суть которых — повторюсь, interoperability.
и — это ваше право
По-моему, вернее будет так:
и это — ваше право
Очень хорошо, что этим занимаются люди. Я, в общем, никогда не писал вэб-сервисы на PHP, и даже наверное не планирую… но все-таки хорошо, что этим люди занимаются и показывают другим как это делать :)
Я в общем к тому, что держите плюс в карму))
Статья оказалась в тему, похоже в моей сфере веб-сервисам найдется применение. Но попытка сделать свой массо-габаритний макет на основе приведеных автором примеров не увенчалась успехом, пока. Пока-что основной трудностью для меня остается отладка (непонятно как обнаружить ошибки в сервере), код выполняется без ошибок, но ведет себя странно. Например, клиент выглядит так:

$client = new SoapClient('http://172.16.3.8/TestServer.wsdl');
$exist = $client->checkUser($_GET['login']);
var_dump($exist);
echo «REQUEST:\n». $client->__getLastRequest(). "\n";
echo «RESPONSE:\n». $client->__getLastResponse(). "\n";
var_dump($client->__getFunctions());

Выдает странное:
object(stdClass)[2]

REQUEST: RESPONSE:

array
0 => string 'checkUserResponse checkUser(checkUser $parameters)' (length=50)

Почему object(stdClass), почему запрос и ответ пустые?

Разбираюсь сам, но может кто подскажет направление, куда копать :)
Я ошибаюсь, или здесь запросы вцикле?

Grabber::run() {
foreach…
}

( Grubber (models/Grabber.php) )
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.