Programmering

JAX-RS med Jersey: En introduktion

JAX-RS (JSR 311: Java API for RESTful Web Services) -specifikationen giver en standardiseret Java-baseret tilgang til implementering af REST-lignende webservices. Jersey er referenceimplementeringen af ​​JAX-RS, og jeg giver en kort introduktion til JAX-RS via Jersey i dette blogindlæg.

Selvom Jersey ikke kræver brug af GlassFish, bruger jeg Jersey sammen med GlassFish v3 i dette indlæg. GlassFish v3 giver referenceimplementeringen til Java EE 6. Jeg downloader GlassFish v3 Windows Installer og kørte den til installation. Efter installationen indstillede jeg miljøvariablen GLASSFISH_HOME for at pege på installationens rodmappe og tilføjet % GLASSFISH_HOME% til min STI. GlassFish kan derefter køres med kommandoen asadmin start-domæne (starter standarddomænet) som vist i næste skærmbillede.

Da jeg brugte standardindstillingerne under min installation af GlassFish, er den webbaserede administrative konsol tilgængelig på min maskine på URI // localhost: 4848 / (standardport er 4848). Når GlassFish kører, fører denne URI til login-siden til den administrative konsol. Det administrative brugernavn og adgangskode blev specificeret i installationen. Denne skærm vises i det næste skærmbillede.

Med GlassFish oprettet går jeg nu videre til at udvikle en meget enkel REST-applikation ved hjælp af Jersey. Jeg starter med en ordentlig JAX-RS-kommenteret klasse kaldet MovieOfTheDay:

MovieOfTheDay.java

pakke rmoug.td2010.rest; import java.util.Calendar; importere java.util.HashMap; importere java.util.Map; importere java.util.logging.Logger; importere javax.ws.rs.GET; importere javax.ws.rs.Path; importere javax.ws.rs.PathParam; importere javax.ws.rs.Consumes; importere javax.ws.rs.Produkter; / ** * Enkel klasse, der giver en film til den angivne måned og dag i den * måned. * / @Path ("/ film") offentlig klasse MovieOfTheDay {privat statisk endelig Logger LOGGER = Logger.getLogger ("rmoug.td2010.rest.MovieOfTheDay"); privat statisk endelig kort MOVIE_OF_THE_DAY; statisk {MOVIE_OF_THE_DAY = nyt HashMap(); endelige kort janMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.JANUARY), janMovies); endelige kort febMovies = nyt HashMap (); febMovies.put (2, "Groundhog Day"); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.FEBRUARY), febMovies); endelig kort marMovies = nyt HashMap (); marMovies.put (16, "The Fugitive"); marMovies.put (17, "Darby O'Gill og de små mennesker"); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.MARCH), marMovies); endelige kort aprMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.APRIL), aprMovies); endelige kort mayMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.MAY), mayMovies); endelig kort junMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.JUNE), junMovies); endelig kort julMovies = nyt HashMap (); julMovies.put (4, "Uafhængighedsdag"); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.JULY), julMovies); endelige kort augMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.AUGUST), augMovies); endelig kort sepMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.SEPTEMBER), sepMovies); endelig kort octMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.OCTOBER), octMovies); endelig kort novMovies = nyt HashMap (); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.NOVEMBER), novMovies); endelig kort decMovies = nyt HashMap (); decMovies.put (24, "Det er et vidunderligt liv"); decMovies.put (25, "A Christmas Carol"); decMovies.put (26, "En julehistorie"); MOVIE_OF_THE_DAY.put (Integer.valueOf (Calendar.DECEMBER), decMovies); } @GET @Path ("/") @Produces ("text / plain") public String getMovie () {return "For at se dagens film skal du angive URL med måned og dag:" + "\ t // localhost : 8080 / resten / ressourcer / film / <> / <> "; } / ** * Få dagens film som angivet med den angivne måned og dato. * * @paramåned Måned for hvilken film af dagen der ønskes. * @param date Dato for hvilken film af dagen der ønskes. * @return Titel på filmens dag i den angivne måned og dato. * / @GET @Path ("/ {month} / {date}") @Consumes ("text / plain") @Produces ("text / html") public String getMovieOfTheDay (@PathParam ("month") final Integer month , @PathParam ("date") endelig helhedsdato) {final Map filmOfTheMonth = MOVIE_OF_THE_DAY.get (måned-1); endelig String movieOfTheDay = filmsOfTheMonth! = null? moviesOfTheMonth.get (dato): "Fletch"; returner movieOfTheDay! = null? createHtml (movieOfTheDay, month, date): createHtml ("Fletch Lives!", month, date); } private String generereHtml (endelig String movieTitle, final int movieMonth, final int movieDay) {final StringBuilder builder = new StringBuilder (); builder.append ("") .append ("Dagens film") .append ("Dagens film") .append ("

Dags film for ") .append (movieMonth) .append (" / ") .append (movieDay) .append (" is '") .append (movieTitle) .append ("'.

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

Den statiske initialiseringsblok er ikke specifik for JAX-RS, men bruges i stedet til at simulere en database. I en rigtig REST-applikation ville jeg næsten helt sikkert have en database på back-end, men det statiske kort i hukommelsen simulerer det her.

Selvom det er simpelt, viser ovenstående klasse vigtige JAX-RS-funktioner. De mest interessante JAX-RS-stykker i klassen er JAX-RS-kommentarerne som @Path, @GET, @Consumes, @Produces og @PathParam. Jeg vil ikke dykke ned i, hvad disse JAX-RS-bemærkninger gør i dette indlæg, fordi min vægt er på at bruge Jersey. Se Java EE 6-vejledningskapitlet om REST with Jersey for at få mere baggrund for disse kommentarer.

Jeg vil distribuere den JAX-RS-kommenterede klasse til GlassFish i en WAR-fil med det relevante web.xml fil som vist næste:

web.xml

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

I mit tilfælde genererede NetBeans 6.8 dette web.xml fil til mig automatisk, når jeg tilføjede de relevante JAX-RS- og Jersey JAR-filer til mit projekts biblioteker. Dette er en relativt enkel web.xml fil på grund af GlassFishs bevidsthed om JAX-RS. (En slående lignende web.xml arbejder for implementering af Jersey-baserede REST-applikationer til Tomcat som vist i Jason Drakes blogindlæg Implementering Jersey i Tomcat 6.0.)

For mit eksempel kaldes en WAR-fil Rest1.war genereres. Indholdet vises i næste skærmbillede.

Som skærmbillede snapshot indikerer, er der JAX-RS og Jersey JAR-filer inkluderet i den genererede WAR-fil. Klassen MovieRestApplication kan ignoreres, fordi det ikke bruges med Jersey på GlassFish. Dette betyder, at de eneste brugerdefinerede filer i WAR er JAX-RS-kommenterede klasse MovieOfTheDay, det web.xml fil og indekssiden (index.jsp). Indholdet af index.jsp siden vises næste.

index.jsp

    HVIL med JAX-RS-eksemplet 

Det næste skærmbillede viser implementering af den genererede WAR-fil via den webbaserede Glass Administrative Console:

Den vigtigste detalje at bemærke fra billedet af implementeringen af ​​WAR-filen er, at jeg har navngivet kontekstroden "hvile". Dette vil være en del af URI'erne, hvorved jeg får adgang til mine implementerede REST-tjenester. Jo tidligere web.xml fil viste også det ressourcer / vil også være en del af denne REST-serviceadgang URI. Resten af ​​den relevante URI er baseret på de stykker URI, der er angivet i JAX-RS-kommentarerne på Java-klassen (/ film, /og / {måned} / {dato}). Dele af URI betegnet med krøllede seler indikerer, at pladsholderne vil blive injiceret med værdier fra JAX-RS-implementeringen, der er i den kaldende URI. For eksempel, hvis det relevante stykke URI var /7/4, dette vil i dette tilfælde indikere en måned på 7. (juli, fordi ikke Java's nulbaserede månedsindeks anvendes i URI) og en dag på 4.

Når implementeringen er vellykket, vises den administrative konsol som vist i næste skærmbillede.

Med JAX-RS-applikationen implementeret kan jeg nu få adgang til den fra et utal af forskellige klienter. JAX-RS angiver ikke en standardiseret tilgang til kunder, men Jersey og de fleste andre populære JAX-RS-implementeringer giver deres egen tilgang til bygningskunder. Andre HTTP / REST-klienter er også tilgængelige, såsom RESTClient. For nu bruger jeg simpelthen en webbrowser.

Placering af URI // localhost: 8080 / i min browser viser hovedsiden, der indikerer, at GlassFish kører:

Hvis jeg tilføjer webkonteksten (hvile) til URI, jeg ser min index.jsp side:

For at få adgang til de JAX-RS-drevne REST-applikationer skal jeg tilføje ressourcer del af URI som specificeret i web.xml fil. Når jeg tilføjer dette plus / film del (som specificeret i @Sti kommentar), jeg ser den næste side.

Ovenstående skærmbillede snapshot angiver, at GET-adgang blev påkaldt med stien "/" og getMovie metode blev kaldt. På dette tidspunkt kan jeg tilføje en måned og en dato til URI for at få en film til den specifikke dag. De næste to skærmbilleder viser dette til Groundhog Day og juledag.

Som ovenstående skærmbillede viser, indsprøjtes de måneder og dage, der er angivet i URI'erne, automatisk af JAX-RS-udbyderen i parametrene til den relevante metode. Nu er det let!

Konklusion

Processen med at implementere en JAX-RS-baseret webservice ved hjælp af Jersey og GlassFish er relativt ligetil. Alt, hvad jeg virkelig havde brug for, var adgang til JAX-RS- og Jersey-JAR'erne, den korrekt kommenterede Java-klasse og den korte web.xml fil, der gjorde det muligt for Jersey at blive brugt som en servlet. Dette blogindlæg har forsøgt at vise de grundlæggende trin involveret i at skrive en simpel JAX-RS-kommenteret klasse, distribuere den til GlassFish og drage fordel af Jerseys implementering af JAX-RS.

Andre ressourcer

⇒ Vejledning til RESTful Web Services-udvikler

⇒ RESTful Java, nogle links

⇒ JSR 311: En Java API til RESTful Web Services?

⇒ Implementering og test af en Jersey-applikation uden NetBeans

⇒ Jersey 1.0: Kom godt i gang

⇒ JSR-311 Javadoc-baseret API

Denne historie, "JAX-RS med Jersey: En introduktion" blev oprindeligt udgivet af JavaWorld.