Донецкий техникум промышленной автоматики

НОУ ІНТУЇТ | лекція | Поліпшення роботи програми фірми ITSO Electronics за допомогою Web-сервісів

  1. 3.8 Імпорт документа WSDL
  2. 3.9 Робота з винятками і помилками в Web-сервісах
  3. 3.10 Безпека в Web-сервісах
  4. 3.11 Використання Web-сервісів за допомогою Java

3.8 Імпорт документа WSDL

Якщо ви імпортуєте документ WSDL, описовий клас генерується на основі змісту документа WSDL. Загальнодоступні прототипи методів, функцій і підстановок в класі відповідають операціям Web-сервіси, певним для першого елемента <port> першого елемента <service> в документі WSDL. Інші класи або типи посилаються на прототипи методів, які, можливо, також будуть згенеровані на підставі вмісту документа WSDL разом з загальнодоступними елементами даних. Якщо ви зміните прототип інтерфейсу, відповідний документ WSDL також зміниться, коли Web-сервіс буде збережений. Ви можете відстежувати подібні зміни за допомогою властивості "Warn if the WSDL interface is modified" (Попереджати, якщо інтерфейс WSDL був змінений).

Бізнес-партнери компанії ITSO Electronics, а, можливо, і покупці, в свою чергу, можуть забезпечувати компанію документом WSDL, який вона може використовувати для створення Web-сервіси. Ви можете імпортувати існуючий документ WSDL, щоб згенерувати каркас Web-сервіси. Каркасний код відповідає опису Web-сервіси. Потім вам необхідно додати код реалізації.

Для того щоб імпортувати документ WSDL, виконайте наступне:

  1. Відкрийте базу даних ITSO Web Services в Domino Designer, потім виберіть Shared Code => Web Services.
  2. Клацніть по кнопці Import WSDL і виберіть файл WSDL, який потрібно імпортувати. У нашому сценарії ми імпортували файл, який експортували в попередньому розділі (див. Мал. 3.14 ).
  3. В результаті імпортування документа WSDL буде згенеровано каркасний код, який в нашому сценарії згенерований на мові LotusScript, як показано в прикладі 3.11 . Потім ми відкрили вікно властивостей Web Service, поставили галочку поруч з опцією Warn if the WSDL interface is modified ( Мал. 3.15 ). % INCLUDE "lsxsd.lss" Class ArrayOfProduct_Holder As INOUT_HOLDER Public Value () As Product End Class Class Product Public description As XSD_STRING Public name As XSD_STRING Public number As Long Public price As Double Sub NEW End Sub End Class Class ProductService Sub NEW End Sub Function getAllProducts () As ArrayOfProduct_Holder End Function Function getProduct (productNumber As Double) As Product End Function End Class Приклад 3.11. Каркасний код, згенерований після імпортування документа WSDL

3.9 Робота з винятками і помилками в Web-сервісах

Операції також можуть повертати помилки за допомогою підкласу помилок, який відповідає деякому повідомленням <wsdl: fault>, обраному для певної операції в документі WSDL, або за допомогою прямого використання базового класу WS_FAULT (LotusScript), або класу lotus.domino.types.Fault, або класу java.lang.Exception (Java).

Зауваження Будь-які помилки в методі опису сервісу на мові LotusScript (т. Е. Будь-який основний клас або підклас WS_FAULT) повинні фігурувати в кінці списку параметрів методу.

Помилки для методу опису сервісу на мові Java виникають в стандартних пропозиціях Java.

Для отримання додаткової інформації про те, як працювати з помилками, використовуючи мову LotusScript см. "Поліпшення роботи програми фірми ITSO Electronics за допомогою Web-сервісів" , "Використання Web-сервіси за допомогою LS2J".

3.10 Безпека в Web-сервісах

Загрози безпеці Web-сервіси, визначених у додатку ITSO Electronics, мають на увазі загрозу всій системі, на якій базується Web-сервіс, з додатком і інфраструктурі мережі в цілому. Для забезпечення захисту Web-сервіси необхідний цілий спектр механізмів захисту, заснованих на мові XML, так як тільки завдяки їм стає можливим вирішення проблем, що стосуються аутентифікації, рольового контролю доступу до баз даних, реалізації принципів забезпечення безпеки, а також безпеки рівня повідомлень, яка виконує роль посередника.

На даний момент не існує загальноприйнятих специфікацій безпеки Web-сервіси. Тому розробники можуть або створювати служби, які не використовують подібних можливостей, або розробляти спеціальні вузькопрофільні програми, які, ймовірно, зможуть вирішувати проблеми функціональної сумісності.

Для застосування Web-сервіси можуть знадобитися механізми захисту "точка-точка" або наскрізні механізми захисту, або обидва механізму в залежності від ступеня загрози або ризику. Традиційні механізми безпеки, побудовані на основі сполук "точка-точка", можливо, не зможуть впоратися з потребами в наскрізний захисту Web-служби. Проте, безпека - це баланс між оціненим ризиком і витратами на протидію. Залежно від допустимої ризику використання захист, що забезпечується сполученням "точка-точка", що працює на рівні переносу даних, дозволяє забезпечити достатніми заходами безпеки.

В архітектурі додатки ITSO Electronics існує три фундаментальних принципи, що відносяться до безпеки: ресурси, які повинні бути захищені; механізми, завдяки яким забезпечується цей захист (т. е. політика захисту); і політики, які представляють собою оброблювані комп'ютерами документи, які, описують обмеження на цих ресурсах. Для продовження дискусії про безпеку застосування Web-сервіси зверніться до керівництва Web Service Architecture, яке доступне за наступною адресою в Інтернеті: http://www.w3.org/TR/2004/NOTE-ws-arch-20040211

Web-сервіс Lotus Domino 7 має ті ж можливості захисту, що і агент. Рівень захисту Web-сервіси встановлюється в закладці Security (Безпека) вікна властивостей Web service. У наведеному нижче списку описуються параметри, доступні в закладці Security.

  • Run as web user (Запускати від імені Web-користувача): код Java або LotusScript запускається з реальним ім'ям користувача, який запустив Web-сервіс.
  • Run on behalf of (Запускати від імені): код Java або LotusScript запускається на повноваження певного користувача. Проте, передплатник Web-сервісу повинен мати необмежені права на сервер або правом запускати Web-сервіси від імені будь-якого користувача.
  • Set runtime security level (Встановити рівень захисту виконання) (один з перерахованих нижче):
    • Do not allow restricted operations (Не дозволяти виконання операцій з обмеженим доступом);
    • Allow restricted operations (Дозволяти виконання операцій з обмеженим доступом);
    • Allow restricted operations with full administration rights (Дозволяти виконання операцій з обмеженим доступом з повними правами адміністрування).
  • Default access for this web service (Доступ за замовчуванням до цього Web-сервісу):
    • All readers and above (Всі читачі і вище). Ви можете вибрати або зняти цей параметр.
    • Enumerated (Перераховані). Якщо ви прибрали галочку поруч з параметром All readers and above, то за допомогою цього параметра ви можете вибрати тих, кому ви хочете надати доступ за замовчуванням.
  • Allow Public Access users to use this web service (Дозволити користувачам відкритого доступу застосовувати цей Web-сервіс). Якщо вибрати цю опцію,, користувачі, що володіють відкритим доступом до документів в базі даних, отримують доступ за замовчуванням.

3.11 Використання Web-сервісів за допомогою Java

На момент написання цієї книги Lotus Domino 7.0 забезпечував, хоча і не в повному обсязі, використання Web-сервіси. Проте, допоміжним бізнес-вимогам, які ставляться до додатка ITSO Electronics, є надання доступу до цінових даних, розташованим за межами Lotus Domino, що, в свою чергу, диктує необхідність використання Web-сервіси в цьому додатку. У нашому сценарії компанія ITSO Electronics вирішила застосувати програмний продукт з відкритим вихідним кодом Apache SOAP, щоб використовувати Web-сервіси за допомогою Java. Apache SOAP є реалізацією стандарту SOAP в W3C. Він замінює собою розробку IBM SOAP4J. Наступний, покращений проект Apache Axis доступний за наступною адресою: http://ws.apache.org/axis/

Для того щоб проілюструвати використання Web-сервіси, в нашому сценарії ми створили окрему базу даних в додатку ITSO Electronics, яку назвали WS Consumer. У цій базі даних міститься агент, який буде використовувати складний Web-сервіс, створений нами раніше.

Зауваження Web-сервіси можуть бути додані до будь-якої базі даних Lotus Notes і Domino. Але для досягнення цілей, поставлених в цій книзі, все Web-сервіси додані до окремих баз даних в додатку ITSO Electronics, які називаються webservices.nsf і wsconsumer.nsf.

Наведена нижче послідовність дій наочно ілюструє створення агента, який використовує Web-сервіс.

  1. Завантажте найновішу версію Apache SOAP за наступним посиланням: http://ws.apache.org/soap/
  2. Вийміть долучення до тимчасової директорію, в нашому сценарії в якості такої папки ми використовували папку c: \ soap.
  3. Експортуйте складний Web-сервіс ProductService (що знаходиться в базі даних Web Services) в документ WSDL. В експортованому документі WSDL міститься вся інформація, необхідна для використання Web-сервісу.
  4. Відкрийте документ WSDL в текстовому редакторі. Документ WSDL містить інформацію, що описує складний тип даних, що повертаються цим Web-сервісом, як видно з прикладу 3.12 . У нашому випадку цей складний тип даних називається Product. Складний елемент Type показує властивості об'єкта Product, до яких відносяться опис, назва, номер і ціна. <Wsdl: types> <schema targetNamespace = "urn: DefaultNamespace" xmlns = "http://www.w3.org/2001/ XMLSchema" xmlns: wsdl = "http://schemas.xmlsoap.org/wsdl/"> <import namespace = "http://schemas.xmlsoap.org/soap/encoding/" /> <complexType name = "Product"> <sequence> <element name = "description" nillable = "true" type = "xsd: string "/> <element name =" name "nillable =" true "type =" xsd: string "/> <element name =" number "type =" xsd: int "/> <element name =" price "type = "xsd: double" /> </ sequence> </ complexType> <complexType name = "ArrayOfProduct"> <complexContent> <restriction base = "soapenc: Array"> <attribute ref = "soapenc: arrayType" wsdl: arrayType = " impl: Product [] "/> </ restriction> </ complexContent> </ complexType> </ schema> </ wsdl: types> Приклад 3.12. Тип WSDL для Product
  5. Відкрийте нову базу даних WS Consumer в Domino Designer, виберіть Shared Code => Agents (Загальний код Агенти), після чого натисніть на кнопку New agent (Створити агент).
  6. В поле Name вікна властивостей Agent введіть ConsumeWS і в розділі Runtime в випадаючому меню Target (Мета) виберіть None (Відсутній), як показано на Мал. 3.16 .
    Мал. 3.16. Вікно властивостей ConsumerWS Agent
  7. Закрийте вікно властивостей Agent, потім виберіть мову коду Java.
  8. Нам необхідно створити клас JavaBean, що представляє складний тип даних Product, визначений у документі WSDL. Для полегшення цієї операції ми скористаємося можливістю імпортування WSDL для автоматичної генерації класу JavaBean. Після цього нам необхідно вибрати Shared Code => Web Service (Загальний код Web-сервіс) і клацнути по кнопці New Web Service (Створити Web-сервіс).
  9. Закрийте вікно властивостей Web Service і переконайтеся в тому, що мова опису Web-сервісу встановлений на Java. Клацніть по кнопці Import WSDL (Імпортувати WSDL), потім виберіть створений раніше документ WSDL. В результаті імпортування цього документа будуть автоматично створені класи JavaBeansTM.
  10. Виділіть і скопіюйте код Java для Product.java.
  11. Поверніться до агента і клацніть по кнопці New Class (Створити клас). Потім замініть клас Untitled.java скопійованих кодом Product.java, так само, як це зроблено в прикладі 3.13 .
  12. Збережіть агент ConsumeWS і переконайтеся в тому, що він був успішно скомпільовано.

    Клацніть по кнопці Edit Project (Змінити проект), відкриється вікно Java Agent Files (див. Мал. 3.17 ). Перейдіть до потрібної директорії бібліотеки SOAP LIB, в нашому випадку ця директорія перебувала за наступним шляхом: c: \ soap \ soap-2_3_1 \ lib. В якості типу файлу виберіть Archive (Архівний), клацніть по кнопці Add / Replace File (s) (Додати / Замінити файли), далі натисніть ОК.

  13. Вам необхідно код JavaAgent.java за замовчуванням замінити своїм власним, щоб приступити до використання Web-сервісу, який в нашому сценарії представлений в прикладі 3.14 . Переконайтеся в тому, що в класі JavaAgent.java є змінні URL і soapAction. Ці змінні повинні вказувати на розташування вашої програми.
  14. Збережіть агент ConsumeWS.
  15. Поверніться до нового Web-сервісу і закрийте його без збереження.
  16. Відкрийте клієнт Lotus Notes і виберіть базу даних WS Consumer. Перейдіть до Actions => ConsumeWS (Дії ConsumeWS) для того, щоб запустити щойно створений агент. Агент відобразить набір об'єктів Product, використовуваних в Web-сервісі, в вікні Java, як видно на Мал. 3.18 .
    Мал. 3.18. Вікно Java, в якому відображено результат роботи Web-сервісу Якщо вікно не відкрилося, виберіть File => Tools => Show Java Debug Console (Файл сервіс Показати консоль налагодження Java) для отримання додаткової інформації.
public class Product {private java.lang.String description; private java.lang.String name; private int number; private double price; public Product () {} public java.lang.String getDescription () {return description; } Public void setDescription (java.lang.String description) this.description = description; } Public java.lang.String getName () {return name; } Public void setName (java.lang.String name) {this.name = name; } Public int getNumber () {return number; } Public void setNumber (int number) {this.number = number; } Public double getPrice () {return price; } Public void setPrice (double price) {this.price = price; } Private java.lang.Object __equalsCalc = null; public synchronized boolean equals (java.lang.Object obj) {if (! (obj instanceof Product)) return false; Product other = (Product) obj; if (obj == null) return false; if (this == obj) return true; if (__equalsCalc! = null) {return (__equalsCalc == obj); } __EqualsCalc = obj; boolean _equals; _equals = true && ((this.description == null && other.getDescription () == null) | (this.description! = null && this.description.equals (other.getDescription ()))) && ((this. name == null && other.getName () == null) || (this.name! = null && this.name.equals (other.getName ()))) && this.number == other.getNumber () && this.price == other.getPrice (); __equalsCalc = null; return _equals; } Private boolean __hashCodeCalc = false; public synchronized int hashCode () {if (__hashCodeCalc) {return 0; } __HashCodeCalc = true; int _hashCode = 1; if (getDescription ()! = null) {_hashCode + = getDescription (). hashCode (); } If (getName ()! = Null) {_hashCode + = getName (). HashCode (); } _HashCode + = getNumber (); _hashCode + = new Double (getPrice ()). hashCode (); __hashCodeCalc = false; return _hashCode; }} Приклад 3.13. Код класу Product import lotus.domino. *; import java.io. *; import java.util. *; import java.net. *; import org.w3c.dom. *; import org.apache.soap.util.xml. *; import org.apache.soap. *; import org.apache.soap.encoding. *; import org.apache.soap.encoding.soapenc. *; import org.apache.soap.rpc. *; import javax.swing. *; public class JavaAgent extends AgentBase {public void NotesMain () {try {Session session = getSession (); AgentContext agentContext = session.getAgentContext (); URL url = new URL ( "http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ ProductService? WSDL"); String soapAction = "http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ ProductService? WSDL"; Call call = new Call (); BeanSerializer beanSerializer = new BeanSerializer (); SOAPMappingRegistry smRegistry = new SOAPMappingRegistry (); smRegistry.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ( "urn: DefaultNamespace", "Product"), Product.class, beanSerializer, beanSerializer); String targetNamespace = "urn: DefaultNamespace"; call.setSOAPMappingRegistry (smRegistry); call.setTargetObjectURI (targetNamespace); call.setMethodName ( "getAllProducts"); call.setEncodingStyleURI (Constants.NS_URI_SOAP_ENC); Response resp = null; try {resp = call.invoke (url, soapAction); } Catch (SOAPException e) {e.printStackTrace (); System.err.println ( "SOAP Exception code:" + e.getFaultCode () + "message:" + e.ge return;} if (! Resp.generatedFault ()) {Parameter ret = resp.getReturnValue (); Product [] products = (Product []) ret.getValue (); buildGUI (products);} else {Fault fault = resp.getFault (); System.err.println ( "SOAP Fault," + fault.getFaultCode () + "" + fault. getFaultS}} catch (Exception e) {e.printStackTrace ();}} private void buildGUI (Product [] products) {StringBuffer sb = new StringBuffer (); String newLine = "<br>"; for (int i = 0; i <products.length; i ++) {sb.append (newLine + newLine); sb.append (products [i] .getName () + "(" + products [i] .getNumber () + ")" + newLine); sb.append ( "*" + products [i] .getDescription ()); sb.append (newLine + "*" + products [i] .getPrice ());} JFrame frame = new JFrame ( "Web service content"); frame.getContentPane (). add (new JScrollPane (new JLabel ( "<html>" + sb. toString () + "</ html>"))); frame.pack () ; frame.setVisible (true);}} Приклад 3.14. Код, необ видимий для використання Web-сервісу за допомогою JavaNsf/ ProductService?
Nsf/ ProductService?