JAX-RS dengan Jersey: Pengantar

Spesifikasi JAX-RS (JSR 311: Java API for RESTful Web Services) menyediakan pendekatan standar berbasis Java untuk mengimplementasikan layanan web gaya REST. Jersey adalah referensi implementasi JAX-RS dan saya memberikan pengenalan singkat tentang JAX-RS melalui Jersey di postingan blog ini.

Meskipun Jersey tidak memerlukan penggunaan GlassFish, saya menggunakan Jersey dalam hubungannya dengan GlassFish v3 dalam posting ini. GlassFish v3 menyediakan implementasi referensi untuk Java EE 6. Saya mengunduh Penginstal Windows GlassFish v3 dan menjalankannya untuk instalasi. Setelah instalasi, saya mengatur variabel lingkungan GLASSFISH_HOMEuntuk menunjuk ke direktori root instalasi dan menambahkannya %GLASSFISH_HOME%ke file PATH. GlassFish kemudian dapat dijalankan dengan perintah asadmin start-domain(memulai domain default) seperti yang ditunjukkan di snapshot layar berikutnya.

Karena saya menggunakan pengaturan default selama instalasi GlassFish saya, konsol administratif berbasis web tersedia di komputer saya di URI // localhost: 4848 / (port default adalah 4848). Dengan GlassFish berjalan, URI ini mengarah ke halaman login untuk Konsol Administratif. Nama pengguna dan kata sandi administratif ditentukan dalam instalasi. Layar ini ditunjukkan pada snapshot layar berikutnya.

Dengan penyiapan GlassFish, saya sekarang beralih ke pengembangan aplikasi REST yang sangat sederhana menggunakan Jersey. Saya mulai dengan kelas beranotasi JAX-RS yang benar yang disebut MovieOfTheDay:

MovieOfTheDay.java

package rmoug.td2010.rest; import java.util.Calendar; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; /** * Simple class that provides a movie for the provided month and day of that * month. */ @Path("/movies") public class MovieOfTheDay { private static final Logger LOGGER = Logger.getLogger("rmoug.td2010.rest.MovieOfTheDay"); private static final Map
    
      MOVIE_OF_THE_DAY; static { MOVIE_OF_THE_DAY = new HashMap
     
      (); final Map janMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.JANUARY), janMovies); final Map febMovies = new HashMap(); febMovies.put(2, "Groundhog Day"); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.FEBRUARY), febMovies); final Map marMovies = new HashMap(); marMovies.put(16, "The Fugitive"); marMovies.put(17, "Darby O'Gill and the Little People"); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.MARCH), marMovies); final Map aprMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.APRIL), aprMovies); final Map mayMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.MAY), mayMovies); final Map junMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.JUNE), junMovies); final Map julMovies = new HashMap(); julMovies.put(4, "Independence Day"); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.JULY), julMovies); final Map augMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.AUGUST), augMovies); final Map sepMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.SEPTEMBER), sepMovies); final Map octMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.OCTOBER), octMovies); final Map novMovies = new HashMap(); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.NOVEMBER), novMovies); final Map decMovies = new HashMap(); decMovies.put(24, "It's A Wonderful Life"); decMovies.put(25, "A Christmas Carol"); decMovies.put(26, "A Christmas Story"); MOVIE_OF_THE_DAY.put(Integer.valueOf(Calendar.DECEMBER), decMovies); } @GET @Path("/") @Produces("text/plain") public String getMovie() { return "To see the movie of the day, provide URL with month and day: " + "\t//localhost:8080/rest/resources/movies/<>/<>"; } /** * Obtain the movie of the day as indicated by the provided month and date. * * @param month Month for which movie of the day is desired. * @param date Date for which movie of the day is desired. * @return Title of the movie of the day for provided month and date. */ @GET @Path("/{month}/{date}") @Consumes("text/plain") @Produces("text/html") public String getMovieOfTheDay( @PathParam("month") final Integer month, @PathParam("date") final Integer date) { final Map moviesOfTheMonth = MOVIE_OF_THE_DAY.get(month-1); final String movieOfTheDay = moviesOfTheMonth != null ? moviesOfTheMonth.get(date) : "Fletch"; return movieOfTheDay != null ? generateHtml(movieOfTheDay, month, date) : generateHtml("Fletch Lives!", month, date); } private String generateHtml( final String movieTitle, final int movieMonth, final int movieDay) { final StringBuilder builder = new StringBuilder(); builder.append("") .append("Movie of the Day") .append("Movie of the Day") .append("
      

The movie of the day for ") .append(movieMonth) .append("/") .append(movieDay) .append(" is '") .append(movieTitle) .append("'.

"); return builder.toString(); } }

Blok inisialisasi statis tidak khusus untuk JAX-RS, tetapi digunakan untuk mensimulasikan database. Dalam aplikasi REST nyata, saya hampir pasti memiliki database di back-end, tetapi peta statis dalam memori mensimulasikan itu di sini.

Meski sederhana, kelas di atas mendemonstrasikan fitur-fitur utama JAX-RS. Bagian JAX-RS yang paling menarik di kelas ini adalah penjelasan JAX-RS seperti @Path, @GET, @Consumes, @Produces, dan @PathParam. Saya tidak akan mempelajari apa yang dilakukan anotasi JAX-RS ini di posting ini karena penekanan saya adalah menggunakan Jersey. Lihat bab Tutorial Java EE 6 di REST dengan Jersey untuk latar belakang lebih lanjut tentang anotasi ini.

Saya akan menerapkan kelas beranotasi JAX-RS ke GlassFish dalam file WAR dengan file yang sesuai web.xmlseperti yang ditunjukkan berikut ini:

web.xml


    
      ServletAdaptor com.sun.jersey.spi.container.servlet.ServletContainer 1 ServletAdaptor /resources/* 30 
    

Dalam kasus saya, NetBeans 6.8 membuat web.xmlfile ini untuk saya secara otomatis ketika saya menambahkan file JAX-RS dan Jersey JAR yang sesuai ke perpustakaan proyek saya. Ini adalah web.xmlfile yang relatif sederhana karena kesadaran GlassFish tentang JAX-RS. (Sebuah web.xmlkarya yang sangat mirip untuk menerapkan aplikasi REST berbasis Jersey ke Tomcat seperti yang ditunjukkan dalam posting blog Jason Drake, Menyebarkan Jersey di Tomcat 6.0.)

Untuk contoh saya, file WAR yang disebut Rest1.wardihasilkan. Isinya ditampilkan di snapshot layar berikutnya.

Seperti yang ditunjukkan oleh snapshot layar, ada file JAX-RS dan Jersey JAR yang disertakan dalam file WAR yang dihasilkan. Kelas MovieRestApplicationdapat diabaikan karena tidak digunakan dengan Jersey di GlassFish. Ini berarti bahwa satu-satunya file kustom dalam WAR adalah kelas beranotasi JAX-RS MovieOfTheDay, web.xmlfile, dan halaman indeks ( index.jsp). Isi index.jsphalaman ditampilkan berikutnya.

index.jsp

    REST with JAX-RS Example   

Cuplikan layar berikutnya menunjukkan penerapan file WAR yang dihasilkan melalui Konsol Administratif Glass berbasis web:

Detail terpenting yang perlu diperhatikan dari gambar penyebaran file WAR adalah bahwa saya telah menamai akar konteks "rest." Ini akan menjadi bagian dari URI yang digunakan untuk mengakses layanan REST saya. File sebelumnya web.xmljuga menunjukkan bahwa itu resources/akan menjadi bagian dari URI akses layanan REST ini juga. Sisa dari URI yang tepat didasarkan pada potongan URI disediakan dalam penjelasan JAX-RS pada kelas Java ( /movies, /, dan /{month}/{date}). Bagian URI yang ditandai dengan tanda kurung kurawal menunjukkan bahwa placeholder akan diinjeksi dengan nilai dari implementasi JAX-RS yang ada di URI pemanggil. Misalnya, jika bagian URI yang relevan adalah/7/4, ini akan menunjukkan, dalam hal ini, bulan 7 (Juli karena tidak menggunakan indeks bulan berbasis nol Java di URI) dan hari ke 4.

Ketika penerapan berhasil, konsol administratif muncul seperti yang ditunjukkan di cuplikan layar berikutnya.

Dengan penerapan JAX-RS, saya sekarang dapat mengaksesnya dari berbagai klien yang berbeda. JAX-RS tidak menjelaskan pendekatan standar untuk klien, tetapi Jersey dan sebagian besar implementasi JAX-RS yang populer menyediakan pendekatan mereka sendiri untuk membangun klien. Klien HTTP / REST lain juga tersedia seperti RESTClient. Untuk saat ini, saya hanya akan menggunakan browser web.

Menempatkan URI // localhost: 8080 / di browser saya menampilkan halaman utama yang menunjukkan bahwa GlassFish sedang berjalan:

Jika saya menambahkan konteks web ( rest) ke URI, saya melihat index.jsphalaman saya :

Untuk mengakses aplikasi REST yang didukung JAX-RS, saya perlu menambahkan resourcesporsi URI seperti yang ditentukan dalam web.xmlfile. Ketika saya menambahkan ini ditambah /moviesporsi (seperti yang ditentukan dalam @Pathpenjelasan), saya melihat halaman berikut.

Cuplikan layar di atas menunjukkan bahwa akses GET dipanggil dengan jalur "/" dan getMoviemetode itu dipanggil. Pada titik ini, saya dapat menambahkan bulan dan tanggal ke URI untuk mendapatkan film pada hari tertentu itu. Dua cuplikan layar berikutnya mendemonstrasikan ini untuk Hari Groundhog dan Hari Natal.

Seperti yang ditunjukkan snapshot layar di atas, bulan dan hari yang disediakan dalam URI secara otomatis dimasukkan oleh penyedia JAX-RS ke dalam parameter untuk metode yang sesuai. Nah, itu mudah!

Kesimpulan

Proses penerapan layanan web berbasis JAX-RS menggunakan Jersey dan GlassFish relatif mudah. Yang saya perlukan hanyalah akses ke JAX-RS dan Jersey JARs, kelas Java yang dianotasi dengan benar, dan web.xmlfile pendek yang memungkinkan Jersey untuk digunakan sebagai servlet. Posting blog ini telah mencoba untuk menunjukkan langkah-langkah dasar yang terlibat dengan penulisan kelas sederhana beranotasi JAX-RS, menerapkannya ke GlassFish, dan memanfaatkan implementasi Jersey dari JAX-RS.

Sumber Daya Lainnya

⇒ Panduan Pengembang Layanan Web RESTful

⇒ Java RESTful, Beberapa Tautan

⇒ JSR 311: API Java untuk Layanan Web RESTful?

⇒ Menerapkan dan Menguji Aplikasi Jersey tanpa NetBeans

⇒ Jersey 1.0: Memulai

⇒ API berbasis JSR-311 Javadoc

Cerita ini, "JAX-RS dengan Jersey: An Introduction" awalnya diterbitkan oleh JavaWorld.