SAAJ: Няма прикачени струни

По време на това писане повечето уеб услуги се състоят от прост обмен на съобщения: Клиент се свързва с уеб услуга и изпраща съобщение до тази услуга. Уеб услугата от своя страна обработва тази заявка и след това изпраща отговор на клиента. Този опростен модел на заявка / отговор моделира начина, по който HTTP протоколът улеснява взаимодействието клиент / уеб сървър. Както при HTTP, обменът на съобщения в уеб услуги често трябва да включва двоично съдържание, като изображения, документи или звукови клипове. Тази статия представя изпращане и получаване на съдържание на двоична уеб услуга, използвайки SOAP (Simple Object Access Protocol) с API за прикачени файлове за Java (SAAJ) 1.2.

Преди да се потопите в тънкостите при прехвърляне на съдържание на двоична уеб услуга, струва си да посочите, че простата услуга в стил заявка / отговор контрастира с услугите, които модират взаимодействие клиент / сървър като отдалечени извиквания на процедури или RPC. В RPC сървърът излага интерфейс, който прилича на API. На свой ред клиентът извиква такава услуга чрез извършване на отдалечени повиквания в API на услугата, предаване на необходимите параметри и получаване на стойностите, които генерира повикването.

Базираният на XML RPC прилича на начина, по който извиквате обекти в обектно-ориентирана (ОО) система. Всъщност, когато работите с Java API за базиран на XML RPC (JAX-RPC), рядко осъзнавате, че работите с XML документи, а не с Java обекти. JAX-RPC ви позволява да мислите за уеб услугите като за отдалечени обекти, както бихте направили с Java RMI (Remote Method Invocation). Времето за изпълнение на JAX-RPC превежда повикванията на метода на високо ниво на OO към XML документи, очаквани от отдалечената уеб услуга. Докато уеб услугите в стил RPC често предоставят по-удобен модел за програмиране, RPC повикванията също трябва да разчитат на слой за съобщения от по-ниско ниво, за да обменят XML съобщенията, съставляващи отдалеченото повикване.

За някои уеб услуги често е полезно да програмирате директно към този слой за съобщения от по-ниско ниво. Например, ако искате да извикате уеб услуга, която консумира документ за поръчка за покупка и връща касова бележка, можете лесно да моделирате този обмен на документи като обмен на единична заявка / отговор. Вместо да правите отдалечени извиквания на методи, вие трябва да конструирате XML съобщения, да ги изпращате директно до уеб услуга и да обработвате XML отговора на услугата, ако има такъв. Тъй като SOAP определя общия формат на съобщенията за съобщения на уеб услуги, ще трябва да създадете съобщения, съответстващи на SOAP, и след като услугата отговори, анализирайте тези съобщения за отговор SOAP обратно във формат, който вашата програма разбира.

SAAJ предоставя удобна библиотека за конструиране и четене на SOAP съобщения, а също така ви позволява да изпращате и получавате SOAP съобщения в мрежата. SAAJ дефинира пространството от имена javax.xml.soap. Класовете, които се намират в този пакет, първоначално представляват част от Java API за XML съобщения (JAXM), но наскоро бяха разделени в техния собствен API. JAXM разчита на SAAJ за изграждане и манипулиране на SOAP съобщения и добавя надеждност на съобщенията и други характеристики, специфични за XML съобщенията. Докато SAAJ е задължителен компонент на J2EE (Java 2 Platform, Enterprise Edition) 1.4, JAXM не е такъв. Тази статия се фокусира върху един от най-полезните аспекти на SAAJ: възможността за прикачване на двоично съдържание към SOAP съобщение.

Ползите от прикачените файлове

Докато дизайнерският център на SOAP се фокусира върху капсулирането на XML документи в съобщение, функцията за прикачване на SOAP разширява SOAP съобщение, за да включва, в допълнение към обикновената SOAP част, нула или повече прикачени файлове, както е показано на Фигура 1. Всеки прикачен файл се дефинира от тип MIME и може да приема всяко съдържание, представено като байтов поток.

Функцията за прикачване на SOAP се оказва най-полезна, когато клиент желае да предаде двоични данни, като изображение или аудио данни, на уеб услуга. Без SOAP прикачени файлове изпращането на бинарни данни би се оказало по-трудно. Например, SOAP съобщението на клиента може да предаде URL адреса на двоичния файл. След това клиентът ще трябва да работи с HTTP сървър, за да позволи на уеб услугата да извлече този файл. Това би представлявало ненужна тежест за всеки клиент на уеб услуги, особено за клиенти, работещи на устройства с ограничени ресурси, като цифрови фотоапарати или скенери. Възможността за прикачване на SOAP позволява на всеки клиент на уеб услуга, способен да предава SOAP съобщения, да вгражда двоични файлове директно в SOAP съобщение.

Приставките SOAP например се оказват полезни при взаимодействие с уебсайтове на портала. Помислете за мрежа от агенции за недвижими имоти, която трябва да разпространява описания и снимки на домове за продажба до централизиран портал за търсене на недвижими имоти. Ако порталът управлява сървлет, позволяващ публикуването на SOAP съобщения с прикачени файлове, агенция за недвижими имоти може да актуализира своите списъци с няколко SOAP съобщения, включително снимки на тези домове. Тялото на SOAP съобщението може да вгражда описанието на свойствата, а SOAP прикачените файлове да носят файловете с изображения. При този сценарий, когато сървлетът на оператора на портала получи такова съобщение, той ще върне документ за потвърждение, указващ наличността на публикацията на портала. Фигура 2 илюстрира такава уеб услуга.

Анатомията на SOAP със съобщение за прикачени файлове

SOAP съобщенията с прикачени файлове W3C (World Wide Web Consortium) Забележка (вж. Ресурси) не добавя нови функции към SOAP. По-скоро той определя как да се възползвате от MIME типовете в SOAP съобщение, за да дефинирате прикачени файлове и как да препращате към тези прикачени файлове от тялото на SOAP.

Типът MIME multipart/relatedдефинира документи, състоящи се от множество свързани части. SOAP съобщенията с прикачени файлове трябва да следват типа multipart/relatedMIME. Примерът по-долу показва multipart/relatedSOAP съобщение, обвързано с HTTP протокола, с две прикачени файлове:

POST / propertyListing HTTP / 1.1 Хост: www.realproperties.com Тип съдържание: Multipart / Свързани; граница = MIME_boundary; тип = текст / xml; Content-Length: NNNN --MIME_boundary Content-Type: text / xml; charset = UTF-8 Content-Transfer-Encoding: 8bit Content-ID: Really Nice Homes, Inc. Добавяне на 1234 Main St Pleasantville CA 94323 250000 --MIME_boundary Content-Type: image / jpeg Content-ID: .... JPEG DATA ..... --MIME_boundary Content-Type: image / jpeg Content-ID: .... JPEG DATA ..... --MIME_boundary--

Горното многочастно съобщение съдържа поредица от MIME заглавки и свързани данни. В основата на документа е тялото на SOAP. Тъй като тялото на SOAP съдържа само XML данни, MIME типът на цялото съобщение е text/xml. След плика SOAP има два прикачени файла, всеки съответстващ на файл с изображение, изпратен заедно със съобщението.

Идентификатор на съдържанието идентифицира всеки прикачен файл. Бележката W3C позволява или идентификатор на съдържание, или местоположение на съдържанието да препраща към прикачените файлове, но дава предпочитание на първите. Такива идентификатори на съдържание действат като препратки към унифициран идентификатор на ресурс (URI) към прикачените файлове; правилата за кодиране SOAP 1.1 определят как да се препраща към ресурс в SOAP съобщение чрез URI, който може да препраща към всяко съдържание, а не само към XML (вижте Раздел 5 на SOAP 1.1 в Ресурси). SOAP процесор разрешава тези URI препратки, докато обработва съобщението. Въз основа на горния пример, SOAP процесорът свързва елемента frontImageс раздела с данни с Content ID [email protected]в SOAP съобщението.

Създайте и изпратете SOAP съобщение с прикачени файлове

SAAJ ви позволява да създавате и редактирате всяка част от SOAP съобщение, включително прикачени файлове. Повечето от SAAJ се основават на абстрактни класове и интерфейси, така че всеки доставчик може да внедри SAAJ в собствените си продукти. Референтната реализация на Sun Microsystems идва с Java Web Services Developer Pack (JWSDP).

Тъй като SOAP съобщенията представляват само специална форма на XML документи, JAAS надгражда API на обектния модел на документ (DOM) за XML обработка. Повечето компоненти на SOAP съобщенията слизат от javax.xml.soap.Nodeинтерфейса, който от своя страна е org.w3c.dom.Nodeподклас. Подкласове SAAJ Nodeза добавяне на специфични за SOAP конструкции. Така например, специален Node, SOAPElementпредставлява елемент SOAP съобщение.

Прекият резултат от разчитането на SAAJ на интерфейси и абстрактни класове е, че изпълнявате повечето задачи, свързани със SOAP, чрез фабрични методи. За да свържете приложението си с SAAJ API, първо създавате a SOAPConnectionот SOAPConnectionFactory. За създаване и редактиране на SOAP съобщения можете също да инициализирате a MessageFactoryи a SOAPFactory. MessageFactoryви позволява да създавате SOAP съобщения и SOAPFactoryпредоставя методите за създаване на отделни части от SOAP съобщение:

SOAPConnectionFactory spConFactory = SOAPConnectionFactory.newInstance (); SOAPConnection con = spConFactory.createConnection (); SOAPFactory soapFactory = SOAPFactory.newInstance ();

С тези инструменти на място можете да създадете SOAP съобщение, което клиент от агенция за недвижими имоти би използвал, за да изпрати актуализация на списъка до уебсайт на портала.

SAAJ предлага няколко начина за създаване на ново SOAP съобщение. Следващият пример показва най-простия метод, който създава празно SOAP съобщение с плик и заглавка и тяло в този плик. Тъй като не се нуждаете от заглавка SOAP в това съобщение, можете да премахнете този елемент от съобщението:

SOAPMessage съобщение = factory.createMessage (); SOAPHeader заглавна част = message.getSOAPHeader (); header.detachNode ();

Добавянето на XML структура към тялото на съобщението се оказва просто:

SOAPBody тяло = message.getSOAPBody (); Име listingElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listingElement = body.addBodyElement (listingElementName); Име attname = soapFactory.createName ("id"); listingElement.addAttribute (attname, "property_1234"); SOAPElement listingAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode ("Наистина хубави домове, Inc"); SOAPElement listingType = listingElement.addChildElement ("listingType"); listingType.addTextNode ("добавяне"); SOAPElement propertyAddress = listingElement.addChildElement ("propertyAddress"); SOAPElement street = propertyAddress.addChildElement ("улица"); street.addTextNode ("1234 Main St "); SOAPElement city = propertyAddress.addChildElement (" city "); city.addTextNode (" Pleasantville "); SOAPElement state = propertyAddress.addChildElement (" state "); state.addTextNode (" CA "); SOAPElement zip = propertyAddress.addChildElement ("zip"); zip.addTextNode ("94521"); SOAPElement listPrice = listingElement.addChildElement ("listPrice"); listPrice.addTextNode ("25000");addChildElement ("listPrice"); listPrice.addTextNode ("25000");addChildElement ("listPrice"); listPrice.addTextNode ("25000");

Обърнете внимание, че добавяте уникалния идентификатор на свойството като атрибут към propertyListingелемента. Освен това вие квалифицирате propertyListingелемента с QNameиме или име, познаващо пространството от имена.

Можете да добавяте прикачени файлове към SOAP съобщението по няколко начина. В този пример първо създавате елементи, за да обозначите предните и вътрешните изображения на изброените свойства. Всеки има hrefатрибут, обозначаващ идентификатора на съдържанието на прикачения файл:

String frontImageID = "[email protected]"; SOAPElement frontImRef = listingElement.addChildElement ("frontImage"); Име hrefAttName = soapFactory.createName ("href"); frontImRef.addAttribute (hrefAttName, frontImageID); String interiorID = "[email protected]"; SOAPElement interiorImRef = listingElement.addChildElement ("interiorImage"); interiorImRef.addAttribute (hrefAttName, interiorID);

За лесно прикачване на необходимите файлове с изображения към съобщението, използвайте javax.activation.DataHandlerобект от JavaBeans Activation Framework. DataHandlerможе автоматично да открие предадения към него тип данни и следователно може автоматично да присвои подходящия тип съдържание MIME на прикачения файл:

URL адрес на URL = нов URL ("файл: ///export/files/pic1.jpg"); DataHandler dataHandler = нов DataHandler (url); AttachmentPart att = message.createAttachmentPart (dataHandler); att.setContentId (frontImageID); message.addAttachmentPart (att);

Като алтернатива може да успеете да предадете Object, заедно с правилния тип MIME, на createAttachmentPart(). Този метод прилича на първия. Вътрешно изпълнението на SAAJ вероятно ще търси a DataContentHandlerза обработка на посочения тип MIME. Ако не може да намери подходящ манипулатор, createAttachmentPart()ще изведе IllegalArgumentException:

URL url2 = нов URL ("файл: ///export/files/pic2.jpg"); Изображение im = Toolkit.getDefaultToolkit (). CreateImage (url2); AttachmentPart att2 = message.createAttachmentPart (im, "image / jpeg"); att2.setContentId (interiorID); message.addAttachmentPart (att2);