Server-Side Java: Menggunakan XML dan JSP secara bersamaan

Untuk keperluan artikel ini saya akan berasumsi bahwa Anda tahu apa itu JavaServer Pages (JSP) dan Extensible Markup Language (XML), tetapi Anda mungkin sedikit tidak jelas tentang bagaimana Anda dapat menggunakannya. Penggunaan JSP cukup mudah untuk dipertahankan. Ini memungkinkan Anda untuk mendesain Situs Web yang dibangun dari file yang terlihat dan bertindak sangat mirip dengan HTML. Satu-satunya perbedaan adalah JSP juga bertindak secara dinamis - misalnya, JSP dapat memproses formulir atau membaca database - menggunakan Java sebagai bahasa skrip sisi server. Penggunaan XML lebih sulit untuk dibenarkan. Meskipun tampaknya setiap produk baru mendukungnya, masing-masing tampaknya menggunakan XML untuk tujuan yang berbeda.

Pada artikel ini, Anda akan belajar mendesain sistem menggunakan XML dengan cara yang cukup sederhana. Banyak Situs Web memiliki koleksi data yang sangat banyak yang ditampilkan dengan cara yang kurang lebih standar. Saya akan merancang sistem yang menggunakan file XML untuk menyimpan data di server Web dan file JSP untuk menampilkan data itu.

XML versus database relasional

"Tapi tunggu," Anda mungkin bertanya, "Anda menggunakan XML untuk menyimpan data? Mengapa tidak menggunakan database?" Pertanyaan bagus. Jawabannya adalah untuk banyak tujuan, database berlebihan. Untuk menggunakan database, Anda harus menginstal dan mendukung proses server terpisah, yang seringkali juga memerlukan penginstalan dan dukungan administrator database. Anda harus mempelajari SQL, dan menulis kueri SQL yang mengonversi data dari relasional ke struktur objek dan kembali lagi. Jika Anda menyimpan data Anda sebagai file XML, Anda kehilangan overhead server tambahan. Anda juga mendapatkan cara mudah untuk mengedit data Anda: cukup gunakan editor teks, daripada alat database yang rumit. File XML juga lebih mudah untuk dicadangkan, untuk dibagikan dengan teman Anda, atau untuk diunduh ke klien Anda. Anda juga dapat dengan mudah mengunggah data baru ke situs Anda, menggunakan FTP.

Keuntungan yang lebih abstrak dari XML adalah, sebagai format hierarki daripada format relasional, XML dapat digunakan dengan cara yang jauh lebih mudah untuk merancang struktur data yang sesuai dengan kebutuhan Anda. Anda tidak perlu menggunakan editor hubungan entitas atau menormalkan skema Anda. Jika Anda memiliki satu elemen yang berisi elemen lain, Anda dapat menyatakannya secara langsung dalam format, daripada menggunakan tabel gabungan.

Perhatikan bahwa untuk banyak aplikasi, sistem berkas tidak akan mencukupi. Jika Anda memiliki volume pembaruan yang tinggi, sistem file mungkin menjadi bingung atau rusak oleh penulisan simultan; database biasanya mendukung transaksi, yang memungkinkan konkurensi tanpa korupsi. Lebih lanjut, database adalah alat yang sangat baik jika Anda perlu membuat kueri yang rumit, terutama jika kueri akan bervariasi dari waktu ke waktu. Basis data membuat indeks, dan dioptimalkan untuk menjaga indeks tetap mutakhir dengan kumpulan data yang terus berubah. Basis data relasional juga memiliki banyak keuntungan lain, termasuk bahasa kueri yang kaya, alat desain skema dan penulisan yang matang, skalabilitas yang terbukti, kontrol akses yang cermat, dan sebagainya.

(Catatan: Anda dapat menggunakan penguncian file sederhana untuk menyediakan server transaksi orang miskin. Dan Anda juga dapat menerapkan alat indeks dan pencarian XML di Java, tetapi itu adalah topik untuk artikel lain.)

Dalam kasus ini, seperti di sebagian besar Situs Web volume rendah hingga menengah, berbasis penerbitan, Anda dapat mengasumsikan hal berikut: sebagian besar akses data adalah membaca, bukan menulis; data, meskipun berpotensi besar, relatif tidak berubah; Anda tidak perlu melakukan pencarian yang rumit, tetapi jika melakukannya, Anda akan menggunakan mesin pencari terpisah. Keuntungan menggunakan RDBMS yang matang memudar, sementara keuntungan menggunakan model data berorientasi objek muncul kedepan.

Terakhir, sangatlah mungkin untuk menyediakan pembungkus untuk database Anda yang membuat kueri SQL dan menerjemahkannya ke dalam aliran XML, sehingga Anda dapat menggunakan keduanya. XML menjadi antarmuka yang lebih kuat dan ramah programmer ke database dewasa untuk menyimpan dan mencari. (Servlet XSQL Oracle adalah salah satu contoh dari teknik ini.)

Aplikasi: Album foto online

Semua orang menyukai foto! Orang suka menunjukkan foto diri, teman, hewan peliharaan, dan liburan mereka. Web adalah media utama bagi para fotografer amatir yang memanjakan diri - mereka dapat mengganggu kerabat mereka dari jarak ribuan mil jauhnya. Sementara situs album foto yang lengkap akan membutuhkan model objek yang rumit, saya akan fokus pada mendefinisikan satu Pictureobjek. (Kode sumber untuk aplikasi ini tersedia di Sumber.) Objek yang mewakili gambar membutuhkan bidang yang mewakili judulnya, tanggal pengambilannya, keterangan opsional, dan, jelas, penunjuk ke sumber gambar.

Sebuah gambar, pada gilirannya, membutuhkan beberapa bidangnya sendiri: lokasi file sumber (GIF atau JPEG) dan tinggi dan lebar dalam piksel (untuk membantu Anda membuat tag). Di sini ada satu keuntungan menggunakan sistem file sebagai database Anda: Anda dapat menyimpan file gambar di direktori yang sama dengan file data.

Terakhir, mari kita perpanjang rekaman gambar dengan elemen yang mendefinisikan sekumpulan gambar mini untuk digunakan dalam daftar isi atau di tempat lain. Di sini saya menggunakan konsep gambar yang sama yang saya definisikan sebelumnya.

Representasi XML dari sebuah gambar bisa terlihat seperti ini:

 Alex On The Beach 1999-08-08 Mencoba sia-sia untuk mendapatkan tan alex-beach.jpg 340 200 alex-beach-sm.jpg 72 72 alex-beach-med.jpg 150 99    

Perhatikan bahwa dengan menggunakan XML, Anda meletakkan semua informasi tentang satu gambar ke dalam satu file, daripada menyebarkannya di antara tiga atau empat tabel terpisah. Mari kita sebut ini .pixfile - sehingga sistem file Anda mungkin terlihat seperti ini:

 summer99 / alex-beach.pix summer99 / alex-beach.jpg summer99 / alex-beach-sm.jpg summer99 / alex-beach-med.jpg summer99 / alex-snorkeling.pix dll. 

Teknik

Ada lebih dari satu cara untuk menguliti kucing, dan ada lebih dari satu cara untuk membawa data XML ke halaman JSP Anda. Berikut adalah daftar dari beberapa cara tersebut. (Daftar ini tidak lengkap; banyak produk dan kerangka kerja lain akan berfungsi sama baiknya.)

  • DOM : Anda dapat menggunakan kelas yang mengimplementasikan antarmuka DOM untuk mengurai dan memeriksa file XML
  • XMLEntryList : Anda dapat menggunakan kode saya untuk memuat XML ke dalam java.util.Listpasangan nama-nilai
  • XPath : Anda dapat menggunakan prosesor XPath (seperti Resin) untuk menemukan elemen dalam file XML berdasarkan nama jalur
  • XSL : Anda dapat menggunakan prosesor XSL untuk mengubah XML menjadi HTML
  • Cocoon : Anda dapat menggunakan framework Cocoon open source
  • Gulung kacang Anda sendiri : Anda dapat menulis kelas pembungkus yang menggunakan salah satu teknik lain untuk memuat data ke dalam JavaBean khusus

Perhatikan bahwa teknik ini dapat diterapkan dengan baik pada aliran XML yang Anda terima dari sumber lain, seperti klien atau server aplikasi.

Halaman JavaServer

Spesifikasi JSP memiliki banyak inkarnasi, dan produk JSP yang berbeda menerapkan versi spesifikasi yang berbeda dan tidak kompatibel. Saya akan menggunakan Tomcat, karena alasan berikut:

  • Ini mendukung versi paling mutakhir dari spesifikasi JSP dan servlet
  • Ini didukung oleh Sun dan Apache
  • Anda dapat menjalankannya secara mandiri tanpa mengkonfigurasi server Web terpisah
  • Ini open source

(Untuk informasi lebih lanjut tentang Tomcat, lihat Sumber.)

Anda dapat menggunakan mesin JSP apa pun yang Anda suka, tetapi mengonfigurasinya terserah Anda! Pastikan mesin mendukung setidaknya spesifikasi JSP 1.0; ada banyak perubahan antara 0,91 dan 1,0. JSWDK (Java Server Web Development Kit) akan bekerja dengan baik.

Struktur JSP

When building a JSP-driven Website (also known as a Webapp), I prefer to put common functions, imports, constants, and variable declarations in a separate file called init.jsp, located in the source code for this article.

I then load that file into each JSP file using . The directive acts like the C language's #include, pulling in the text of the included file (here, init.jsp) and compiling it as if it were part of the including file (here, picture.jsp). By contrast, the tag compiles the file as a separate JSP file and embeds a call to it in the compiled JSP.

Finding the file

When the JSP starts, the first thing it needs to do after initialization is find the XML file you want. How does it know which of the many files you need? The answer is from a CGI parameter. The user will invoke the JSP with the URL picture.jsp?file=summer99/alex-beach.pix (or by passing a file parameter through an HTML form).

However, when the JSP receives the parameter, you're still only halfway there. You still need to know where on the filesystem the root directory lies. For example, on a Unix system, the actual file may be in the directory /home/alex/public_html/pictures/summer99/alex-beach.pix. JSPs do not have a concept of a current directory while executing, so you need to provide an absolute pathname to the java.io package.

The Servlet API provides a method to turn a URL path, relative to the current JSP or Servlet, into an absolute filesystem path. The method ServletContext.getRealPath(String) does the trick. Every JSP has a ServletContext object called application, so the code would be:

String picturefile = application.getRealPath("/" + request.getParameter("file")); 

or

String picturefile = getServletContext().getRealPath("/" + request.getParameter("file")); 

which also works inside a servlet. (You must append a / because the method expects to be passed the results of request.getPathInfo().)

One important note: whenever you access local resources, be very careful to validate the incoming data. A hacker, or a careless user, can send bogus data to hack your site. For instance, consider what would happen if the value file=../../../../etc/passwd were entered. The user could in this way read your server's password file.

The Document Object Model

DOM stands for the Document Object Model. It is a standard API for browsing XML documents, developed by the World Wide Web Consortium (W3C). The interfaces are in package org.w3c.dom and are documented at the W3C site (see Resources).

There are many DOM parser implementations available. I have chosen IBM's XML4J, but you can use any DOM parser. This is because the DOM is a set of interfaces, not classes -- and all DOM parsers must return objects that faithfully implement those interfaces.

Unfortunately, though standard, the DOM has two major flaws:

  1. The API, though object-oriented, is fairly cumbersome.
  2. There is no standard API for a DOM parser, so, while each parser returns a org.w3c.dom.Document object, the means of initializing the parser and loading the file itself is always parser specific.

The simple picture file described above is represented in the DOM by several objects in a tree structure.

Document Node --> Element Node "picture" --> Text Node "\n " (whitespace) --> Element Node "title" --> Text Node "Alex On The Beach" --> Element Node "date" --> ... etc. 

To acquire the value Alex On The Beach you would have to make several method calls, walking the DOM tree. Further, the parser may choose to intersperse any number of whitespace text nodes, through which you would have to loop and either ignore or concatenate (you can correct this by calling the normalize() method). The parser may also include separate nodes for XML entities (like &), CDATA nodes, or other element nodes (for instance, the big bear would turn into at least three nodes, one of which is a b element, containing a text node, containing the text big). There is no method in the DOM to simply say "get me the text value of the title element." In short, walking the DOM is a bit cumbersome. (See the XPath section of this article for an alternative to DOM.)

From a higher perspective, the problem with DOM is that the XML objects are not available directly as Java objects, but they must be accessed piecemeal via the DOM API. See my conclusion for a discussion of Java-XML Data Binding technology, which uses this straight-to-Java approach for accessing XML data.

I have written a small utility class, called DOMUtils, that contains static methods for performing common DOM tasks. For instance, to acquire the text content of the title child element of the root (picture) element, you would write the following code:

Document doc = DOMUtils.xml4jParse(picturefile); Element nodeRoot = doc.getDocumentElement(); Node nodeTitle = DOMUtils.getChild(nodeRoot, "title"); String title = (nodeTitle == null) ? null : DOMUtils.getTextValue(nodeTitle); 

Getting the values for the image subelements is equally straightforward:

Node nodeImage = DOMUtils.getChild(nodeRoot, "image"); Node nodeSrc = DOMUtils.getChild(nodeImage, "src"); String src = DOMUtils.getTextValue(nodeSrc); 

And so on.

Once you have Java variables for each relevant element, all you must do is embed the variables inside your HTML markup, using standard JSP tags.

   

See the full source code for more details. The HTML output produced by the JSP file -- an HTML screenshot, if you will -- is in picture-dom.html.