Главная » Java, Web, XML » Создание простейшей Java Web-службы

0

Продолжим рассмотрение примера метеослужбы и опишем ее классом Java. Назовем этот класс MeteoService. Наша метеослужба предоставляет только одну Web-услугу — прогноз погоды на завтра. Пусть эта услуга предоставляется методом getweatherForecast о. Не будем изощряться в сложных алгоритмах прогнозирования погоды, а просто дадим наиболее вероятный для России прогноз.

В листинге 2.1 приведено описание нашей Web-службы. - Листинг 2.1. Класс, описывающий простейшую Web-службу

public class MeteoService {

public String getweatherForecast (String location) ; return location + ": пойдет дождь или снег" ;

)

}

Воспользуемся Axis для реализации нашей Web-службы. Для этого запишем исходный текст класса        в файл  (расширение

имени файла ".jws" означает "Java Web Service"), а файл занесем в каталог axis нашего сервера приложений, использующего Axis. Каталог axis должен быть вложен в каталог                   сервера приложений.

Все, Web-служба создана и готова предоставить свои услуги любому клиенту. Не нужна ни компиляция, ни установка класса MeteoService в Web- контейнер. Получив SOAP-послание, обращающееся к Web-службе прямо через файл MeteoService.jws, сервер приложений, увидев расширение имени файла ".jws", обратится к Axis, точнее к сервлету AxisServiet. С этого серв- лета Axis начинает работу на сервере.

В листинге 2.2 приведен клиент метеослужбы, написанный просто как Java- приложение, использующее Axis.

Листинг 2.2. Клиент метеослужбы, написанный с помощью Axis

import org. apache. axis. client.Call; import org.apache.axis.client.Service; import

import java.net.*;

public class MeteoServiceClientf

public static void main (String [ ] args) throws Exception;

if (args. length != 1){

System.err.println("Usage: " +

"java MeteoServiceClient <location>");

System.exit(1);

I

Service service = new Service();

Call call = (Call)service.createCall();

String endpoint =

"http://www.meteo.com:8080/axis/MeteoService.jws";

call.setTargetEndpointAddress(new URL(endpoint)); call.setOperationName(new QName ("getWeatherForecast"));

String result =

(String)call.invoke(new Object[]{new String(args[0])});

System.out.println("погода на завтра: " + result);

}

}

Откомпилируем программу листинга 2.2 на машине клиента:

$ javac MeteoServiceClient. java и запустим программу-клиент: $ java MeteoServiceClient Гадюкино На консоли увидим прогноз погоды на завтра.

Как видите, для получения услуги надо только знать адрес URL Web- службы, размещенной в файле MeteoService.jws, и передать ей имя населенного пункта. Все остальное Axis берет на себя.

Посмотрим подробнее на то, что делает Axis в листинге 2.2. Вначале создается объект класса service. Этот объект установит связь с Web-службой. Он предоставляет экземпляр класса call, в котором формируется HTTP- запрос, содержащий SOAP-послание. Для создания запроса в объект класса Call заносится адрес Web-службы и имя Web-услуги "getWeatherForecast". После того как запрос сформирован, Axis обращается к Web-услуге методом invoke (). Аргумент этого метода — массив объектов — содержит аргументы предоставляемой Web-услуги.

Запрос направляется по сети серверу приложений, работающему по указанному в запросе адресу URL. Сервер приложений запускает сервлет играющий роль диспетчера и контейнера, в котором работают Web-службы. Он разбирает SOAP-послание, пришедшее в запросе, отыскивает указанный в послании файл MeteoService.jws и компилирует его содержимое. Затем Axis загружает    class и обращается к методу getWeatherForecast передав ему аргумент. После выполнения этого метода Axis формирует SOAP-ответ и отправляет его клиенту.

Клиентская часть Axis разбирает полученный ответ и передает его как результат выполнения метода invoke ().

Программу-клиент Web-службы, показанную в листинге 2.2, можно встроить в клиентское приложение или использовать отдельно, снабдив ее графическим интерфейсом.

Запрос, сформированный Axis и посылаемый клиентом нашей метеослужбы на сервер, без HTTP-заголовка выглядит буквально так, как показано в листинге 2.3.

I Листинг 2.3. SOAP-послание клиента метеослужбы

<?xrnl version="1.0" encoding="UTF-8"?>

<S0AP-ENV:Envelope

SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<SOAP-ENV:Body>

<getWeatherForecast>

<argO xsi:type="xsd:string">ra,njoKMHO<:/arg0> </getWeatherForecast>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Как видите, нигде в запросе нет упоминания о платформе, на которой работает клиент, и тем более не сказано, что клиентом должно быть Java- приложение. Поэтому клиентом Axis может быть любая программа, способная составить такой запрос и разобрать ответ сервера. Ее можно написать на любом языке. Поскольку книга посвящена созданию Web Services с помощью Java, приведем в листинге 2.4 клиент, написанный только стандартными сетевыми средствами Java, без использования Axis.

Листинг 2.4. Клиент метеослужбы

import j ava.net.*; import j ava.io.*;

public class MeteoServiceClient2{

public static void main(String[] args){

if (args.length != 1) {

System.err.println("Usage: " +

"javaMeteoServiceClient2 <location>");

System.exit(1);

}

String message =

"<?xml version^’1.0′ encoding=’UTF-8’?>" + "<SOAP-ENV:Envelope" +

"SOAP-ENV:encodingStyle=" +

"’http://schemas.xmlsoap.org/soap/encoding/’" + "xmlns:SOAP-ENV=’http://schemas.xmlsoap.org/soap/envelope/’" + "xmlns:xsd=’http://www.w3.org/2001/XMLSchema’" + "xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’" + "xmlns:SOAP-ENC=’http://schemas.xmlsoap.org/soap/encoding/’>" + "<SOAP-ENV:Body>" +

"<getWeatherForecast>" +

"<arg0 xsi:type=’xsd:string’>" + args[0] + "</argO>" + "</getWeatherForecast>" + "</SOAP-ENV:Body>" + "</SOAP-ENV:Envelope>";

try{

byte[] data = message.getBytes("K0I8-R");

URL url =

new URL("http://www.meteo.com:8080/axis/MeteoService.jws");

URLConnection uc = url.openConnection();

uc.setDoOutput(true); uc.setDoInput(true); uc.setUseCaches(false);

uc.setRequestProperty("Content-Type", "text/xml;charset=\"ut f-8\"");

uc.setRequestProperty("Content-Length", ""+ message.length () ) ;

uc.connect() ;

DataOutputStream dos =

new DataOutputStream(uc.getOutputStreamO);

dos.write(data, 0, data.length); dos.close ();

BufferedReader br = new BufferedReader( new inputStreamReader(

uc.getlnputStream(), "K0I8-R"));

String res = null;

while ((res = br. readLine () ) != null) System.out.println(res);

br.close();

}catch(Exception e){

System.err.println("From client: " + e); e.printStackTrace(System.out);

}

}

}

Ответ, полученный клиентом в листинге 2.4, приведен в листинге 2.5. Листинг 2.5. SOAP-ответ метеослужбы

<?xml version = "1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope

xmlns:SOAP-ENV=’http://schemas.xmlsoap.org/soap/envelope/’

xmlns:xsd=’http://www.w3.org/2 О 01/XMLSchema’

xmlns:xs i=’http://www.w3.org/2001/XMLSchema-instance’> <SOAP-ENV:Body>

<getWeatherForecastResponse SOAP-ENV: e:ncodingStyle=

‘http://schemas.xmlsoap.org/soap/encoding/’>

<getWeatherForecastResult xsi:type=’xsd:string’>

Гадюкино: пойдет дождь или снег </getWeatherForecastResult>

</getWeatherForecastResponse>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Конечно, клиент, показанный в листинге 2.4, должен еще разобрать ответ, присланный сервером в виде SOAP-послания листинга 2.5, выделив из него результат — прогноз погоды. Для этого придется применить SAX-napcep, один из описанных в главе 1. Не будем сейчас заниматься этим.

Внимательный читатель заметил, что та часть Axis на сервере, которая принимает SOAP-послания, оформлена в виде сервлета AxisServiet. Действительно, в технологии Java Web-службы реализуются сервлетами и страницами JSP, которые, еюзможно, обращаются к компонентам EJB типа SLSB (Stateless Session Beam) или типа MDB (MessageDriven Bean). Нашу простую метеослужбу можно реализовать без Axis одним сервлетом, например, таким, какой показан в листинге 2.6.

Листинг 2.6. Сервлет. реализующий метеослужбу

import j ava. io. *;

import java.util.*;

import javax.servlet.http.*;

public class MeteoServiceServlet extends HttpServlet{

public String getWeatherForecast(String location))

return location + ": пойдет дождь или снег";

}

public void doPost (HttpServletRequest req,

HttpServletResponse resp){

try{

req.setCharacterEncoding("K0I8-R" ) ; BufferedReader br = req.getReader();

String message = " " , buf = " " , location = " " ;

while ((tuf = br. readLine () ) ! = null) message += buf;

// Анализ SOAP-послания message SAX-парсером и // выделение аргумента location.

resp.setContentType("text/xml; charset=\"utf-8\"");

String response =

"<?xml version=’1.0′ encoding=’UTF-8’?>" + "<SOAP-ENV:Envelope" +

+

+

+

+

+

+

+

+

+

"</getWeatherForecastResult>" +

"</getWeatherForecastResponse>" + +

"</SOAP-ENV:Envelope>";

PrintWriter pw = resp.getWriter(); pw.println(response);

pw. flush () ;

pw.close();

}catch(Exception e){

System.err.println(e);

}

}

}

Вся наша простейшая метеослужба уместилась в одном методе getWeatherForecast (). В реальной ситуации ее лучше вынести в один или несколько компонентов EJB.

Итак, построить любую Java Web-службу можно стандартными свободно доступными средствами Java, имеющимися в пакетах инструментальных средств J2SDK SE, J2SDK ЕЕ и WSDP. Их можно свободно загрузить с сайта http://java.sun.com/.

Литература:

Хабибуллин И. Ш. Разработка Web-служб средствами Java. — СПб.: БХВ-Петербург, 2003. — 400 с: ил.

По теме:

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