SAAJ: Tanpa pamrih

Pada saat penulisan ini, sebagian besar layanan Web terdiri dari pertukaran pesan sederhana: Klien menghubungi layanan Web dan mengirim pesan ke layanan itu. Layanan Web, pada gilirannya, memproses permintaan itu dan kemudian mengirim balasan ke klien. Pola permintaan / respons sederhana itu memodelkan cara protokol HTTP memfasilitasi interaksi klien / server Web. Seperti HTTP, pertukaran pesan layanan Web sering kali harus menyertakan konten biner, seperti gambar, dokumen, atau klip suara. Artikel ini memperkenalkan pengiriman dan penerimaan konten layanan Web biner menggunakan SOAP (Simple Object Access Protocol) dengan Attachments API for Java (SAAJ) 1.2.

Sebelum menyelami seluk-beluk mentransfer konten layanan Web biner, ada baiknya menunjukkan bahwa layanan Web bergaya permintaan / respons sederhana berbeda dengan layanan yang membuat interaksi klien / server sebagai panggilan prosedur jarak jauh, atau RPC. Dalam RPC, server memperlihatkan antarmuka yang menyerupai API. Pada gilirannya, klien memanggil layanan semacam itu dengan melakukan panggilan jarak jauh pada API layanan, meneruskan parameter yang diperlukan, dan menerima nilai yang dihasilkan panggilan tersebut.

RPC berbasis XML menyerupai cara Anda memanggil objek dalam sistem berorientasi objek (OO). Memang, saat bekerja dengan Java API untuk RPC berbasis XML (JAX-RPC), Anda jarang menyadari bahwa Anda sedang bekerja dengan dokumen XML, bukan objek Java. JAX-RPC memungkinkan Anda menganggap layanan Web sebagai objek jarak jauh, seperti yang Anda lakukan dengan Java RMI (Remote Method Invocation). Runtime JAX-RPC menerjemahkan panggilan metode OO tingkat tinggi ke dokumen XML yang diharapkan oleh layanan Web jarak jauh. Sementara layanan Web gaya RPC sering menyediakan model pemrograman yang lebih nyaman, panggilan RPC juga harus bergantung pada lapisan pesan tingkat rendah untuk bertukar pesan XML yang membentuk panggilan jarak jauh.

Untuk beberapa layanan Web, sering kali berguna untuk memprogram secara langsung ke lapisan perpesanan tingkat yang lebih rendah. Misalnya, jika Anda ingin menjalankan layanan Web yang menggunakan dokumen pesanan pembelian dan mengembalikan tanda terima, Anda dapat dengan mudah membuat model pertukaran dokumen tersebut sebagai pertukaran pesan permintaan / tanggapan tunggal. Alih-alih membuat pemanggilan metode jarak jauh, Anda akan membuat pesan XML, mengirim pesan tersebut langsung ke layanan Web, dan memproses respons XML layanan, jika ada. Karena SOAP mendefinisikan format pesan umum untuk pesan layanan Web, Anda perlu membuat pesan yang sesuai dengan SOAP, dan, setelah layanan merespons, parsing pesan respons SOAP tersebut kembali ke dalam format yang dipahami oleh program Anda.

SAAJ menyediakan perpustakaan yang nyaman untuk membuat dan membaca pesan SOAP, dan juga memungkinkan Anda mengirim dan menerima pesan SOAP di seluruh jaringan. SAAJ mendefinisikan namespace javax.xml.soap. Kelas-kelas yang berada dalam paket itu awalnya merupakan bagian dari Java API for XML Messaging (JAXM), tetapi baru-baru ini dipisahkan ke dalam API-nya sendiri. JAXM mengandalkan SAAJ untuk konstruksi dan manipulasi pesan SOAP, dan menambahkan keandalan pesan dan fitur lain yang khusus untuk pesan XML. Sedangkan SAAJ adalah komponen yang dibutuhkan dari J2EE (Java 2 Platform, Enterprise Edition) 1.4, JAXM tidak. Artikel ini berfokus pada salah satu aspek SAAJ yang paling berguna: kemampuan untuk melampirkan konten biner ke pesan SOAP.

Manfaat kemelekatan

Sementara pusat desain SOAP berfokus pada enkapsulasi dokumen XML dalam sebuah pesan, fitur lampiran SOAP memperluas pesan SOAP untuk menyertakan, selain bagian SOAP biasa, tidak ada atau lebih lampiran, seperti yang ditunjukkan Gambar 1. Setiap lampiran ditentukan oleh tipe MIME dan dapat mengasumsikan konten apa pun yang direpresentasikan sebagai aliran byte.

Fitur lampiran SOAP terbukti paling berguna ketika klien ingin mengirimkan data biner, seperti data gambar atau audio, ke layanan Web. Tanpa lampiran SOAP, mengirim sepotong data biner akan terbukti lebih sulit. Misalnya, pesan SOAP klien dapat menyampaikan alamat URL file biner. Klien kemudian harus mengoperasikan server HTTP agar layanan Web mengambil file itu. Itu akan mewakili beban yang tidak semestinya pada klien layanan Web mana pun, terutama pada klien yang berjalan pada perangkat sumber daya terbatas seperti kamera digital atau pemindai. Kemampuan lampiran SOAP memungkinkan setiap klien layanan Web dapat mengirimkan pesan SOAP menanamkan file biner secara langsung dalam pesan SOAP.

Lampiran SOAP, misalnya, terbukti berguna saat berinteraksi dengan Situs Web portal. Pertimbangkan jaringan agen real estat yang perlu mendistribusikan deskripsi dan foto rumah yang akan dijual ke portal pencarian real estat terpusat. Jika portal mengoperasikan servlet yang memungkinkan pengeposan pesan SOAP dengan lampiran, agen real estate dapat memperbarui daftar dengan beberapa pesan SOAP, termasuk foto rumah tersebut. Badan pesan SOAP mungkin menyematkan deskripsi properti, dan lampiran SOAP dapat membawa file gambar. Dalam skenario itu, ketika servlet operator portal menerima pesan seperti itu, itu akan mengembalikan dokumen pengakuan, menunjukkan ketersediaan posting di portal. Gambar 2 mengilustrasikan layanan Web semacam itu.

Anatomi SOAP dengan pesan lampiran

Pesan SOAP dengan Lampiran W3C (World Wide Web Consortium) Catatan (lihat Sumberdaya) tidak menambahkan fitur baru ke SOAP. Sebaliknya, ini mendefinisikan bagaimana memanfaatkan tipe MIME dalam pesan SOAP untuk mendefinisikan lampiran, dan bagaimana mereferensikan lampiran tersebut dari dalam badan SOAP.

Tipe MIME multipart/relatedmendefinisikan dokumen yang terdiri dari beberapa bagian terkait. Pesan SOAP dengan lampiran harus mengikuti multipart/relatedjenis MIME. Contoh di bawah ini menunjukkan multipart/relatedpesan SOAP, terikat ke protokol HTTP, dengan dua lampiran:

POST / propertyListing HTTP / 1.1 Host: www.realproperties.com Jenis Konten: Multipart / Terkait; boundary = MIME_boundary; ketik = teks / xml; Panjang Konten: NNNN --MIME_boundary Jenis Konten: 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 Jenis Konten: image / jpeg ID Konten: .... JPEG DATA ..... --MIME_boundary Content-Type: image / jpeg Content-ID: .... JPEG DATA ..... --MIME_boundary--

Pesan multi bagian di atas terdiri dari serangkaian header MIME dan data terkait. Di akar dokumen adalah badan SOAP. Karena badan SOAP hanya berisi data XML, tipe MIME dari seluruh pesan adalah text/xml. Setelah amplop SOAP ada dua lampiran, masing-masing sesuai dengan file gambar yang dikirim bersama dengan pesan tersebut.

ID konten mengidentifikasi setiap lampiran. Catatan W3C memungkinkan salah satu ID konten atau lokasi konten mereferensikan lampiran, tetapi memberikan preferensi ke yang sebelumnya. ID konten tersebut bertindak sebagai referensi Uniform Resource Identifier (URI) untuk lampiran; aturan pengkodean SOAP 1.1 menentukan cara mereferensikan sumber daya dalam pesan SOAP melalui URI yang dapat mereferensikan konten apa pun, bukan hanya XML (lihat Bagian 5 dari SOAP 1.1 di Sumber Daya). Prosesor SOAP menyelesaikan referensi URI tersebut saat memproses pesan. Berdasarkan contoh di atas, prosesor SOAP mengaitkan elemen frontImagedengan bagian data dengan ID Konten [email protected]dalam pesan SOAP.

Buat dan kirim pesan SOAP dengan lampiran

SAAJ memungkinkan Anda membuat dan mengedit bagian mana pun dari pesan SOAP, termasuk lampiran. Sebagian besar SAAJ didasarkan pada kelas dan antarmuka abstrak sehingga setiap penyedia dapat mengimplementasikan SAAJ dalam produknya sendiri. Implementasi referensi Sun Microsystems hadir dengan Java Web Services Developer Pack (JWSDP).

Karena pesan SOAP hanya mewakili bentuk khusus dari dokumen XML, JAAS dibangun di atas API Document Object Model (DOM) untuk pemrosesan XML. Sebagian besar komponen pesan SOAP diturunkan dari javax.xml.soap.Nodeantarmuka, yang pada gilirannya merupakan org.w3c.dom.Nodesubkelas. SAAJ Nodeuntuk menambahkan konstruksi khusus SOAP. Misalnya, khusus sebuah Node, SOAPElement, merupakan elemen pesan SOAP.

Akibat langsung dari ketergantungan SAAJ pada antarmuka dan kelas abstrak adalah Anda menyelesaikan sebagian besar tugas terkait SOAP melalui metode pabrik. Untuk menghubungkan aplikasi Anda dengan SAAJ API, Anda terlebih dahulu membuat SOAPConnectiondari a SOAPConnectionFactory. Untuk membuat dan mengedit pesan SOAP, Anda juga dapat menginisialisasi a MessageFactorydan a SOAPFactory. MessageFactorymemungkinkan Anda membuat pesan SOAP, dan SOAPFactorymenyediakan metode untuk membuat bagian individual dari pesan SOAP:

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

Dengan alat ini, Anda dapat membuat pesan SOAP yang akan digunakan klien dari agen real estat untuk mengirim pembaruan daftar ke Situs web portal.

SAAJ menawarkan beberapa cara untuk membuat pesan SOAP baru. Contoh berikut menunjukkan metode paling sederhana yang membuat pesan SOAP kosong dengan amplop, dan header dan isi dalam amplop itu. Karena Anda tidak memerlukan header SOAP dalam pesan ini, Anda dapat menghapus elemen tersebut dari pesan:

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

Menambahkan struktur XML ke badan pesan terbukti langsung:

SOAPBody body = message.getSOAPBody (); Name listingElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listingElement = body.addBodyElement (listingElementName); Nama attname = soapFactory.createName ("id"); listingElement.addAttribute (attname, "property_1234"); SOAPElement listingAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode ("Really Nice Homes, Inc"); SOAPElement listingType = listingElement.addChildElement ("listingType"); listingType.addTextNode ("add"); SOAPElement propertyAddress = listingElement.addChildElement ("propertyAddress"); SOAPElement jalan = propertyAddress.addChildElement ("jalan"); 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");

Perhatikan Anda menambahkan ID unik properti sebagai atribut ke propertyListingelemen. Selanjutnya, Anda memenuhi syarat propertyListingelemen dengan QName, atau nama yang peka namespace.

Anda dapat menambahkan lampiran ke pesan SOAP dengan beberapa cara. Dalam contoh ini, Anda terlebih dahulu membuat elemen untuk menunjukkan gambar depan dan interior properti yang terdaftar. Masing-masing memiliki hrefatribut yang menunjukkan ID konten 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 dengan mudah melampirkan file gambar yang diperlukan ke pesan, gunakan javax.activation.DataHandlerobjek dari Kerangka Aktivasi JavaBeans. DataHandlerdapat secara otomatis mendeteksi tipe data yang diteruskan padanya, dan oleh karena itu dapat secara otomatis menetapkan tipe konten 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);

Atau, Anda mungkin bisa meneruskan Object, bersama dengan tipe MIME yang benar, ke createAttachmentPart(). Metode itu mirip dengan yang pertama. Secara internal, implementasi SAAJ kemungkinan akan mencari a DataContentHandleruntuk menangani tipe MIME yang ditentukan. Jika tidak dapat menemukan pawang yang cocok, createAttachmentPart()akan melempar IllegalArgumentException:

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