Июнь 2004


Тема номера: Web-сервисы


Джейсон Прайс

Построение PL/SQL веб-сервисов
(Build a PL/SQL Web Service,
by Jason Price)

Источник: http://otn.oracle.com/pub/articles/price_10gws.html

Oracle Database 10g веб-сервисы позволяют вам получить отдачу от вложений в разработку на PL/SQL и SQL при взаимодействии с внешними веб-сервисами на уровне базы данных. В данной статье показано, как это сделать.

Как мы уже знаем, веб-сервисы доказали свою эффективность при взаимодействии приложений. Протокол веб-сервисов, такой как XML – де-факто стандарт для обмена информацией; SOAP позволяет обмениваться XML документами в распределённой среде поверх HTTP, FTP, и SMTP; WSDL и UDDI позволяют строить платформо- и языконезависимые слабо связанные распределённые приложения.

В базе данных Oracle 10g и сервере приложений Oracle (OracleAS) 10g (посредством OC4J встроенного в OracleAS) можно предоставлять и потреблять веб-сервисы. База данных Oracle 10g позволяет предоставить функциональность для веб-сервисов используя PL/SQL (пакеты, процедуры, функции и триггеры), SQL запросы, SQL DML выражения и Java хранимые процедуры; Веб-сервисы OracleAS дают возможность использовать J2EE (Enterprise JavaBeans, JMS, и т.д.). Вы также можете предоставлять функциональность БД как J2EE веб-сервис, используя OracleAS.

Данная статья, однако, фокусируется только на PL/SQL веб-сервисах базы данных. Веб-сервисы базы данных Oracle 10g по определению предоставляют функциональность в базе данных; позволяют извлекать выгоду из инвестиций в разработку на PL/SQL и SQL при использовании внешних веб-сервисов на уровне базы данных.

Данная статья является введением в веб-сервисы базы данных, из неё можно узнать как создавать, публиковать и запускать PL/SQL веб-сервисы в базе данных Oracle 10g. Все скрипты и файлы, на которые есть ссылки в данной статье, доступны здесь.

Требуемое программное обеспечение

Перед тем как начать работу с примерами, Вам надо будет установить следующее программное обеспечение:

Установка схемы базы данных

Для начала установим схему базы данных, являющейся упрощённым примером Интернет-магазина.

Создадим пользователя с именем store и предоставим ему необходимые права (надо войти в базу данных под пользователем с привилегией CREATE USER):

CREATE USER store IDENTIFIED BY store;
GRANT connect, resource TO store;

На заметку: Вы найдёте данные выражения и другие, необходимые для создания схемы store, в файле web_services.sql.

Следующие два предложения содержат подсоединение к базе данных и создание последовательности order_sq, используемой для заполнения первичного ключа в таблице заказов:

CREATE TABLE product_types (
  product_type_id INTEGER
    CONSTRAINT product_types_pk PRIMARY KEY,
  name VARCHAR2(10) NOT NULL
);

CREATE TABLE products (
  product_id INTEGER
    CONSTRAINT products_pk PRIMARY KEY,
  product_type_id INTEGER
    CONSTRAINT products_fk_product_types
    REFERENCES product_types(product_type_id),
  name VARCHAR2(30) NOT NULL,
  description VARCHAR2(50),
  price NUMBER(5, 2)
);

CREATE TABLE customers (
  customer_id INTEGER
    CONSTRAINT customers_pk PRIMARY KEY,
  first_name VARCHAR2(10) NOT NULL,
  last_name VARCHAR2(10) NOT NULL,
  dob DATE,
  phone VARCHAR2(12)
);

CREATE TABLE orders (
  order_id INTEGER
    CONSTRAINT orders_pk PRIMARY KEY,
  product_id INTEGER
    CONSTRAINT purchases_fk_products
    REFERENCES products(product_id),
  customer_id INTEGER
    CONSTRAINT purchases_fk_customers
    REFERENCES customers(customer_id),
  quantity INTEGER NOT NULL
);

На заметку: Если создавать таблицы в другой схеме, то надо будет изменить имя схемы в конфигурационных файлах примера.

Таблица product_types используется для хранения названий типов товаров, таблица products содержит детальную информацию о продажах товаров, таблица customers содержит информацию о покупателях, которым разрешено размещать заказы в магазине, и таблица orders содержит данные о том какой пользователь размещал заказы на товары.

Следующее выражение INSERT добавляет строки в таблицы customers, product_types и products:

 INSERT INTO customers (
  customer_id, first_name, last_name, dob, phone
) VALUES (
  1, 'John', 'Brown', '01-JAN-1965', '800-555-1211'
);

INSERT INTO product_types (
  product_type_id, name
) VALUES (
  1, 'Book'
);

INSERT INTO products (
  product_id, product_type_id, name, description, price
) VALUES (
  1, 1, 'Modern Science', 'A description of modern science', 19.95
);

COMMIT;

Мы будем использовать PL/SQL для создания кода для нашего веб-сервиса базы данных. PL/SQL код должен быть помещён в пакет перед тем как вы сможете публиковать его как веб-сервис. Выражения в Листинге1 создают пакет PL/SQL, содержащий процедуры, позволяющие пользователям размещать заказы на товары. Пакет назван dbfunc и содержит процедуру place_order() в которую передается ID товара, ID покупателя, и количество купленных товаров.

Как можно видеть, функция place_order() проверяет находится ли ID товара и ID покупателя в таблицах products и customers, и если да, то добавляет строку в таблицу заказов и возвращает строку, содержащую ID заказа (которая является значением, генерируемым последовательностью order_sq). Если ID покупателя или ID товара неверно, тогда возвращается строка, содержащая сообщение "Нет такого пользователя" или "Нет такого товара".

Теперь давайте установим и конфигурируем OC4J.

Установка и конфигурирование OC4J

Надо установить OC4J используя следующие команды (Я использовал командную строку Windows 2000 при написании статьи; Вы можете использовать аналогичные команды в Unix или Linux шелле, заменив обратный слэш прямым):

e:
cd e:\oracle\oc4j\j2ee\home
java -jar oc4j.jar -install

Затем вам будет предложено ввести администраторский пароль. Я использовал welcome.

Далее надо определить источник данных в файле data-sources.xml, из директории oc4j\j2ee\home\config, добавив секцию, аналогичную следующему элементу:

 
<data-source
  class="com.evermind.sql.DriverManagerDataSource"
  name="OracleDS"
  location="jdbc/OracleCoreDS"
  xa-location="jdbc/xa/OracleXADS"
  ejb-location="jdbc/OracleDS"
  connection-driver="oracle.jdbc.driver.OracleDriver"
  username="store"
  password="store"
  url="jdbc:oracle:thin:@localhost:1521:ORCL"
  inactivity-timeout="30"
/>

На заметку: пример файла data-sources.xml можно найти на веб-сайте OTN. Возможно вам надо будет сменить название сервиса базы данных Oracle — в моем файле используется дефолтный ORCL как идентификатор сервиса (SID) и он запущен локально, и Oracle Net слушает порт 1521. Если ваша база данных запущена на другом сервере, имеет отличный номер порта и другой SID, тогда вам придется сделать соответствующие исправления. Ваш DBA может предоставить необходимую информацию о деталях соединения с базой данных. Также, если таблицы примеров созданы другой схеме, то надо изменить имя и пароль в файле data-sources.xml.

Далее надо стартовать OC4J с помощью следующей команды:

e:
cd e:\oracle\oc4j\j2ee\home
java -jar oc4j.jar

Соответствующее сообщение должно подтвердить, что OC4J стартовал.

Публикация пакета PL/SQL как веб-сервиса базы данных.

Теперь давайте рассмотрим как публиковать PL/SQL пакет dbfunc как веб-сервис.

В сущности, веб-сервис базы данных использует функциональность OC4J для предоставления Java класса – ваш класс Java действует как оболочка вокруг реализации веб-сервиса базы данных. Реализация может быть написана на SQL или хранимых процедурах Java, так же как и на PL/SQL.

Пакет PL/SQL можно опубликовать используя веб-сервисную ассемблерное приложение (web services assembler tool), поставляемое вместе с OC4J версии 9.0.3 или более поздней. Приложению надо передать файл config.xml; config.xml содержит информацию о пакете PL/SQL в схеме базы данных, который вы хотите опубликовать как веб-сервис. Листинг 2 содержит пример файла config.xml file, используемый в нашем примере. (Можно также использовать JDeveloper для публикации веб-сервисов, но про это рассказывает другая статья: "Web Services Development Made Easy," by Elangovan Balusamy.)

Потребуется внести изменения в элемент db-url, если ваша база данных работает на другом сервере, имеет другой номер порта или другой SID чем localhost, 1521 и ORCL соответственно. Раздел httpServerURL содержит сервер и номер порта на котором запущен OC4J - по умолчанию localhost и 8888. Если ваш OC4J запущен на другом сервере и имеет отличный номер порта, то следует отредактировать config.xml file. (На заметку: Установки сервера и порта можно найти в файле http-web-site.xml в директории j2ee\home\config, куда вы установили OC4J. Также, если таблицы примеров созданы в другой схеме, надо изменить имя схемы в установках файла config.xml)

Для публикации dbfunc как веб-сервиса, надо выполнить следующие команды:

 set ORACLE_HOME=E:\oracle\oc4j

set CLASSPATH=.;%ORACLE_HOME%\webservices\lib\wsdl.jar;%ORACLE_HOME%
  \lib\xmlparserv2.jar;%ORACLE_HOME%\soap\lib\soap.jar

java -jar %ORACLE_HOME%\webservices\lib\WebServicesAssembler.jar -config 
  G:\OTN_articles\dws\config.xml

java -jar %ORACLE_HOME%\j2ee\home\admin.jar 
  ormi://localhost admin welcome -deploy -file ./dbfunc.ear -deploymentName dbfunc

java -jar %ORACLE_HOME%\j2ee\home\admin.jar 
  ormi://localhost admin welcome -bindWebApp dbfunc dbfunc_web http-web-site /plsqlsample

ormi://localhost admin welcome -bindWebApp dbfunc dbfunc_web http-web-site /plsqlsample

Первые две команды устанавливают требуемые значения переменных окружения ORACLE_HOME и CLASSPATH. Значение ORACLE_HOME надо установить соответственно директории, в которую была установлена stand-alone версия OC4J. Переменная CLASSPATH содержит местоположение необходимых JAR-файлов для развертывания веб-сервисов. Третья команда использует JAR-файл WebServicesAssembler для публикации веб-сервисов используя файл config.xml. (Необходимо изменить директорию в опции -config на место, где находится файл config.xml) Четвертая команда инсталлирует веб-сервис с именем "dbfunc." (Если вы используете другой пароль, его соответственно надо будет указать) Пятая команда связывает веб-сервис dbfunc с дефолтным веб сайтом http-web-site с относительным путем /plsqlsample. (На заметку: Если вы инсталлируете на OC4J встроенный в Oracle 9iAS, в пятой команде надо заменить http-web-site на default-web-site).

Теперь, когда мы успешно опубликовали наш веб-сервис, пришло время запустить его. Давайте это сделаем.

Запуск веб-сервиса базы данных

Для запуска можно использовать браузер. Наберите в адресной строке следущий url:

http://localhost:8888/plsqlsample/dbfunc

(На заметку: Если ваш OC4J запущен на другом сервере и использует другой порт, это надо указать в адресной строке. Также, если вы инсталлировали сервис на OC4J встроенный в Oracle 9iAS, вам потребуется узнать номер порта из конфигурационных файлов)

Рис 1 демонстрирует станицу, отображенную на моем компьютере.


Рис 1

Если Вы кликните на ссылке Service Description вы увидите XML, содержащий WSDL описание веб-сервиса. (См. Листинг 3.)

Как можно видеть, Листинг 3 содержит WSDL описание веб-сервиса. Следующие строки в WSDL показывают входные параметры и один выходной параметр:

- <message name="placeOrderInput">
  <part name="param0" type="xsd:decimal" /> 
  <part name="param1" type="xsd:decimal" /> 
  <part name="param2" type="xsd:decimal" /> 
  </message>
- <message name="placeOrderOutput">
  <part name="output" type="xsd:string" /> 
  </message>

Три входных параметра являются числами, которые передаются в PL/SQL функцию place_order(); эти числа – ID товара, ID покупателя и количество соответственно. Выходной параметр – это строка, возвращаемая функцией place_order(), и содержащая сообщение об успешности размещения заказа.

Возвращаясь назад к странице на Рис 1, можно кликнуть на ссылку placeOrder. Следующая страница показана на Рис 2; на ней можно указать три необходимых числовых параметра для функции placeOrder() как можно видеть на Рис.2, я указал 1, 1, и 2 для ID товара, ID покупателя и количества соответственно.


Рис. 2

Далее надо нажать кнопку Invoke для запуска веб-сервиса. Выполнение происходит посредством SOAP. После небольшой задержки во время которой веб-сервис стартует и выполняет процедуру, вы увидите результат работы в своём браузере, пример которого показан на Рис 3


Рис. 3

Следующие шаги:

Скачайте примеры веб-сервисов базы данных и How-To's

Прочтите OC4J 10g (10.0.3.0.0) Developer Preview Enterprise Web Services How-To

Скачайте базу данных Oracle 10g

Скачайте OC4J 10g (10.0.3) Developer Preview 2 (только для разработки и тестирования среды)

Посетите страницу Oracle Database Web Services

Из Рисунка 3 вы можете видеть что сообщение SOAP от веб-сервиса отобразилось в вашем браузере, и строка, которую вернула функция place_order() это "Order placed with ID of 1" в элементе xsd:string. Значение 1 пришло от последовательности order_sq. На заметку: если вы используете веб-сервис несколько раз, вы увидите что значение увеличивается на единицу каждый раз.

Между тем в базе данных функция place_order() вставляет строку в таблицу заказов. Эту строку можно увидеть, подключившись к базе данных с помощью SQL*Plus и выполнив следующую операцию SELECT:

SQL> SELECT * FROM orders WHERE order_id = 1;

  ORDER_ID PRODUCT_ID CUSTOMER_ID   QUANTITY
---------- ---------- ----------- ----------
         1          1           1          2

Заметьте, что значения колонок содержат указанные ранее значения.

Если вы попробуете разместить заказ на несуществующий продукт (например, товар с ID=3) используя веб-сервис, вы увидите результат, показанный на Рис 4.


Рис 4

На рисунке 4 можно увидеть строку, возвращённую функцией place_order() "No such product". Если попробовать разместить заказ от имени несуществующего покупателя, то вернется строка "No such customer." В любом случае, никаких строк в таблицу заказов вставлено не будет.

База данных также может использовать веб-сервисы. Эта возможность позволяет вашей базе данных выполнять такие действия как отслеживание, агрегирование и обновление данных, генерируемых удаленными веб-сервисами. Веб сервисы можно потреблять по протоколу SOAP и использовать Oracle Java Virtual Machine или PL/SQL для запуска удаленных веб-сервисов. Можно передавать параметры в веб-сервисы из базы данных и определять виртуальные таблицы базы данных для хранения данных, полученных от веб-сервисов. За деталями обращайтесь к Oracle Database Java Developer's Guide 10g Release 1.


Технический консультант и писатель Джейсон Прайс (Jason Price) - сертифицированный администратор базы данных Oracle и разработчик приложений с более чем 10-летним стажем работы в области программного обеспечения. Автор книг Oracle Database 10g SQL (McGraw-Hill/Osborne, 2004), Oracle9i JDBC Programming (McGraw-Hill/Osborne, 2002), и Java Programming with Oracle SQLJ (O'Reilly, 2001).

E-mail this page