SAAJ: Tiada tali

Pada masa penulisan ini, kebanyakan perkhidmatan Web terdiri daripada pertukaran pesanan ringkas: Pelanggan menghubungi perkhidmatan Web dan menghantar mesej ke perkhidmatan tersebut. Perkhidmatan Web, pada gilirannya, memproses permintaan itu dan kemudian mengirimkan balasan kepada pelanggan. Corak permintaan / respons yang sederhana itu memodelkan cara protokol HTTP memudahkan interaksi pelanggan / pelayan Web. Seperti HTTP, pertukaran mesej perkhidmatan Web selalunya mesti merangkumi kandungan binari, seperti gambar, dokumen, atau klip suara. Artikel ini memperkenalkan pengiriman dan penerimaan kandungan perkhidmatan Web binari menggunakan SOAP (Simple Object Access Protocol) dengan Lampiran API untuk Java (SAAJ) 1.2.

Sebelum menyelami selok-belok memindahkan kandungan perkhidmatan Web binari, perlu diperhatikan bahawa perkhidmatan Web gaya permintaan / respons mudah berbeza dengan perkhidmatan yang menjadikan interaksi pelanggan / pelayan sebagai panggilan prosedur jarak jauh, atau RPC. Dalam RPC, pelayan memperlihatkan antara muka yang menyerupai API. Pada gilirannya, pelanggan memanggil perkhidmatan sedemikian dengan membuat panggilan jarak jauh di API perkhidmatan, melewati parameter yang diperlukan, dan menerima nilai yang dihasilkan oleh panggilan tersebut.

RPC berasaskan XML menyerupai cara anda menggunakan objek dalam sistem berorientasikan objek (OO). Memang, ketika bekerja dengan Java API untuk RPC berbasis XML (JAX-RPC), Anda jarang menyadari bahwa Anda bekerja dengan dokumen XML, bukan objek Java. JAX-RPC memungkinkan anda menganggap perkhidmatan Web sebagai objek terpencil, seperti yang anda lakukan dengan Java RMI (Permintaan Kaedah Jauh). JAX-RPC runtime menerjemahkan panggilan OO kaedah tinggi ke dokumen XML yang diharapkan oleh perkhidmatan Web jauh. Walaupun perkhidmatan Web gaya RPC sering menyediakan model pengaturcaraan yang lebih mudah, panggilan RPC juga harus bergantung pada lapisan pemesejan tingkat bawah untuk menukar pesan XML yang membentuk panggilan jarak jauh.

Untuk beberapa perkhidmatan Web, sering berguna untuk memprogram secara langsung ke lapisan pemesejan tingkat bawah itu. Sebagai contoh, jika anda ingin menggunakan perkhidmatan Web yang menggunakan dokumen pesanan pembelian dan mengembalikan resit, anda dapat dengan mudah memodel pertukaran dokumen itu sebagai pertukaran pesanan / permintaan pesanan tunggal. Daripada membuat panggilan kaedah jarak jauh, anda akan membina mesej XML, mengirim mesej tersebut terus ke perkhidmatan Web, dan memproses respons XML perkhidmatan, jika ada. Oleh kerana SOAP mendefinisikan format pesanan umum untuk mesej perkhidmatan Web, anda perlu membina pesanan yang sesuai dengan SOAP, dan, apabila perkhidmatan itu bertindak balas, menguraikan kembali mesej respons SOAP tersebut ke dalam format yang difahami oleh program anda.

SAAJ menyediakan perpustakaan yang sesuai untuk membina dan membaca mesej SOAP, dan juga membolehkan anda menghantar dan menerima mesej SOAP di seluruh rangkaian. SAAJ mentakrifkan ruang nama javax.xml.soap. Kelas-kelas yang terdapat dalam paket itu pada awalnya merupakan bagian dari Java API untuk Pemesejan XML (JAXM), tetapi baru-baru ini dipisahkan menjadi API mereka sendiri. JAXM bergantung pada SAAJ untuk pembinaan dan manipulasi mesej SOAP, dan menambah kebolehpercayaan mesej dan ciri lain yang khusus untuk pesanan XML. Walaupun SAAJ adalah komponen yang diperlukan dari J2EE (Java 2 Platform, Enterprise Edition) 1.4, JAXM tidak. Artikel ini memberi tumpuan kepada salah satu aspek SAAJ yang paling berguna: keupayaan untuk melampirkan kandungan binari ke mesej SOAP.

Kelebihan lampiran

Walaupun pusat reka bentuk SOAP memfokuskan pada merangkum dokumen XML dalam sebuah pesan, fitur lampiran SOAP memperluas pesan SOAP untuk memasukkan, sebagai tambahan kepada bahagian SOAP biasa, sifar atau lebih banyak lampiran, seperti yang ditunjukkan oleh Gambar 1. Setiap lampiran didefinisikan oleh jenis MIME dan boleh menganggap kandungan yang diwakili sebagai aliran bait.

Ciri lampiran SOAP terbukti paling berguna apabila pelanggan ingin menghantar data binari, seperti gambar atau data audio, ke perkhidmatan Web. Tanpa lampiran SOAP, menghantar sekeping data binari akan menjadi lebih sukar. Contohnya, pesanan SOAP pelanggan boleh menyampaikan alamat URL fail binari. Pelanggan kemudiannya harus mengendalikan pelayan HTTP untuk membiarkan perkhidmatan Web mengambil fail tersebut. Itu akan memberikan beban yang tidak semestinya kepada mana-mana pelanggan perkhidmatan Web, terutama pada klien yang menggunakan peranti sumber terhad seperti kamera digital atau pengimbas. Keupayaan lampiran SOAP membolehkan mana-mana pelanggan perkhidmatan Web dapat menghantar mesej SOAP menanamkan fail binari secara langsung dalam mesej SOAP.

Lampiran SOAP, misalnya, terbukti berguna ketika berinteraksi dengan Laman Web portal. Pertimbangkan rangkaian agensi harta tanah yang perlu menyebarkan keterangan dan gambar kediaman untuk dijual ke portal carian harta tanah terpusat. Sekiranya portal tersebut menggunakan servlet yang membenarkan penyampaian mesej SOAP dengan lampiran, agensi harta tanah boleh mengemas kini senarai dengan beberapa mesej SOAP, termasuk foto rumah tersebut. Badan pesan SOAP mungkin menyertakan keterangan harta tanah, dan lampiran SOAP dapat membawa file gambar. Di bawah senario itu, apabila servlet pengendali portal menerima mesej seperti itu, ia akan mengembalikan dokumen pengakuan, yang menunjukkan ketersediaan pos di portal. Gambar 2 menggambarkan perkhidmatan Web seperti itu.

Anatomi SOAP dengan mesej lampiran

Nota Mesej SOAP dengan Lampiran W3C (World Wide Web Consortium) (lihat Sumber) tidak menambah ciri baru ke SOAP. Sebaliknya, ia menentukan bagaimana memanfaatkan jenis MIME dalam pesan SOAP untuk menentukan lampiran, dan bagaimana merujuk lampiran tersebut dari dalam badan SOAP.

Jenis MIME multipart/relatedmentakrifkan dokumen yang terdiri daripada beberapa bahagian yang berkaitan. Mesej SOAP dengan lampiran mesti mengikut multipart/relatedjenis MIME. Contoh di bawah menunjukkan multipart/relatedmesej SOAP, terikat pada protokol HTTP, dengan dua lampiran:

POST / propertyListing HTTP / 1.1 Host: www.realproperties.com Jenis Kandungan: Multipart / Berkaitan; sempadan = MIME_batas; taip = teks / xml; Panjang Kandungan: NNNN --MIME_batas Kandungan-Jenis: teks / xml; charset = UTF-8 Content-Transfer-Encoding: 8bit Content-ID: Really Nice Homes, Inc. Tambahkan 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--

Mesej berbilang bahagian di atas merangkumi rangkaian header MIME dan data yang berkaitan. Pada akar dokumen adalah badan SOAP. Kerana badan SOAP hanya mengandungi data XML, jenis MIME dari keseluruhan mesej adalah text/xml. Berikutan sampul surat SOAP terdapat dua lampiran, masing-masing sesuai dengan fail gambar yang dihantar bersama dengan pesan.

ID kandungan mengenal pasti setiap lampiran. Catatan W3C membolehkan ID kandungan atau lokasi kandungan merujuk lampiran, tetapi memberikan keutamaan kepada yang sebelumnya. ID kandungan sedemikian bertindak sebagai rujukan Pengenal Sumber Uniform (URI) pada lampiran; peraturan pengekodan SOAP 1.1 menentukan cara merujuk sumber dalam pesan SOAP melalui URI yang dapat merujuk kandungan apa pun, bukan hanya XML (lihat Bahagian 5 SOAP 1.1 dalam Sumber). Pemproses SOAP menyelesaikan rujukan URI tersebut semasa memproses mesej. Berdasarkan contoh di atas, pemproses SOAP mengaitkan elemen frontImagedengan bahagian data dengan Content ID [email protected]dalam mesej SOAP.

Buat dan hantarkan mesej SOAP dengan lampiran

SAAJ membolehkan anda membuat dan mengedit mana-mana bahagian mesej SOAP, termasuk lampiran. Sebilangan besar SAAJ didasarkan pada kelas abstrak dan antara muka sehingga setiap penyedia dapat menerapkan SAAJ dalam produknya sendiri. Pelaksanaan rujukan Sun Microsystems disertakan dengan Pek Pembangun Perkhidmatan Web Java (JWSDP).

Oleh kerana mesej SOAP mewakili tetapi bentuk khas dokumen XML, JAAS menggunakan API Model Objek Dokumen (DOM) untuk pemprosesan XML. Sebilangan besar komponen pesanan SOAP turun dari javax.xml.soap.Nodeantara muka, yang seterusnya merupakan org.w3c.dom.Nodesubkelas. Subkelas SAAJ Nodeuntuk menambah konstruk khusus SOAP. Sebagai contoh, special a Node, SOAPElement, mewakili elemen mesej SOAP.

Hasil langsung dari pergantungan SAAJ pada antara muka dan kelas abstrak ialah anda menyelesaikan kebanyakan tugas yang berkaitan dengan SOAP melalui kaedah kilang. Untuk menghubungkan aplikasi anda dengan SAAJ API, pertama-tama anda membuat a SOAPConnectiondari a SOAPConnectionFactory. Untuk membuat dan mengedit pesanan SOAP, anda juga dapat menginisialisasi a MessageFactorydan a SOAPFactory. MessageFactorymembolehkan anda membuat mesej SOAP, dan SOAPFactorymenyediakan kaedah untuk membuat bahagian individu dari mesej SOAP:

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

Dengan adanya alat ini, anda dapat membuat pesanan SOAP yang akan digunakan oleh pelanggan dari agensi harta tanah untuk menghantar kemas kini penyenaraian ke laman web portal.

SAAJ menawarkan beberapa cara untuk membuat mesej SOAP baru. Contoh berikut menunjukkan kaedah termudah yang menghasilkan mesej SOAP kosong dengan sampul surat, dan tajuk dan badan dalam sampul surat itu. Oleh kerana anda tidak memerlukan tajuk SOAP dalam mesej ini, anda boleh membuang elemen tersebut dari mesej:

Mesej SOAPMessage = factory.createMessage (); SOAPHeader header = message.getSOAPHeader (); header.detachNode ();

Menambah struktur XML ke badan mesej terbukti mudah:

SOAPBody body = message.getSOAPBody (); Senarai namaElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listingElement = body.addBodyElement (listingElementName); Nama attname = soapFactory.createName ("id"); listingElement.addAttribute (nama nama, "property_1234"); SOAPElement listingAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode ("Really Nice Homes, Inc"); SOAPElement listingType = listingElement.addChildElement ("listingType"); listingType.addTextNode ("tambah"); SOAPElement propertyAddress = listingElement.addChildElement ("propertyAddress"); SOAPElement street = propertyAddress.addChildElement ("jalan"); street.addTextNode ("1234 Main St "); SOAPElement city = propertyAddress.addChildElement (" city "); city.addTextNode (" Pleasantville "); SOAPElement state = propertyAddress.addChildElement (" state "); state.addTextNode (" CA "); zip SOAPElement = propertyAddress.addChildElement ("zip"); zip.addTextNode ("94521"); SOAPElement listPrice = listingElement.addChildElement ("listPrice"); listPrice.addTextNode ("25000");addChildElement ("listPrice"); listPrice.addTextNode ("25000");addChildElement ("listPrice"); listPrice.addTextNode ("25000");

Perhatikan bahawa anda menambahkan ID unik harta sebagai atribut ke propertyListingelemen. Selanjutnya, anda melayakkan propertyListingelemen dengan nama QName, atau nama yang sedar ruang.

Anda boleh menambahkan lampiran pada mesej SOAP dengan beberapa cara. Dalam contoh ini, pertama anda membuat elemen untuk menunjukkan gambar depan dan dalaman harta tanah yang disenaraikan. Masing-masing mempunyai hrefatribut yang menetapkan ID kandungan lampiran:

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

Untuk melampirkan fail gambar yang diperlukan dengan mudah ke pesan, gunakan javax.activation.DataHandlerobjek dari Kerangka Pengaktifan JavaBeans. DataHandlersecara automatik dapat mengesan jenis data yang disampaikan kepadanya, dan oleh itu ia dapat secara automatik menetapkan jenis kandungan MIME yang sesuai ke lampiran:

URL url = URL baru ("file: ///export/files/pic1.jpg"); DataHandler dataHandler = DataHandler baru (url); AttachmentPart att = message.createAttachmentPart (dataHandler); att.setContentId (frontImageID); message.addAttachmentPart (att);

Sebagai alternatif, anda mungkin dapat memberikan Object, bersama dengan jenis MIME yang betul, ke createAttachmentPart(). Kaedah itu menyerupai kaedah pertama. Secara dalaman, pelaksanaan SAAJ kemungkinan akan mencari cara DataContentHandleruntuk menangani jenis MIME yang ditentukan. Sekiranya tidak menemui pengendali yang sesuai, createAttachmentPart()akan membuang IllegalArgumentException:

URL url2 = URL baru ("file: ///export/files/pic2.jpg"); Imej im = Toolkit.getDefaultToolkit (). CreateImage (url2); AttachmentPart att2 = message.createAttachmentPart (im, "image / jpeg"); att2.setContentId (interiorID); message.addAttachmentPart (att2);