Bruke REST i Java

Fri 26 August 2011

Som en oppfølger til

I eksemplene gjør vi bruk av noen ekstra pakker, men alle er gratis og tilgjengelige på nett.

  • Java SDK (Doh) .
  • Apache Tomcat / Glassfish e.v.t annen applikasjonssever som kjører JSP.
  • Jakarta Commons HTTPClient
  • Jakarta Commons Logging
  • Jakarta Commons Codec

Når vi skal benytte oss av RESTfulle tjenester (heretter bare kallt tjenester) er mye av arbeidet knyttet til å lese en representasjon av en ressurs. Det er derfor viktig å kunne velge den klienten som passer best til formålet, f.eks kommandolinje, desktop program eller nettbasert applikasjon.

Kommandolinje klient, versjon 1 (java.net)

{codecitation style="brush:java"}

package rest.cli;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class RestCLI {
public static void main(String[] args) {
try {
URL twitter = new URL("http://twitter.com/statuses/public_timeline.json");
URLConnection tc = twitter.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Dette er så enkelt som vi kan få det. Som du ser er det ikke mange linjene som skal til for å få lage en fullverdig REST klient. I eksempelet over kobler vi oss til Twitter sin API og får tilbake de siste 20 statusoppdateringene. Gangen i koden over er relativ enkel, og består av følgende trinn:

  1. Instansier en URL
  2. Åpne en URLConnection
  3. Kjør en HTTP GET request ( twitter.openConnection() )
  4. Les XML dataene som kommer i retur (i vår tilfelle bruker vi en InputStreamReader for å sendei de til en BufferedReader)
  5. Pakk det hele inn i en try / catch sånn at vi ikke kræsjer når noe feiler

Når vi kjører koden over får vi følgende (for å spare plass har jeg kuttet vekk de 19 siste oppdateringene)

{codecitation class="brush: xml;" width="700px" }

run:
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<created_at>Sat Aug 27 12:29:27 +0000 2011</created_at>
<id>107429516841984000</id>
<text>Zo tosti maken</text>
<source>&lt;a href=&quot;http://ubersocial.com&quot; rel=&quot;nofollow&quot;&gt;UberSocial for BlackBerry&lt;/a&gt;</source>
<truncated>false</truncated>
<favorited>false</favorited>
<in_reply_to_status_id></in_reply_to_status_id>
<in_reply_to_user_id></in_reply_to_user_id>
<in_reply_to_screen_name></in_reply_to_screen_name>
<retweet_count>0</retweet_count>
<retweeted>false</retweeted>
<user>
<id>199341232</id>
<name>NF=NFB</name>
<screen_name>superman010_</screen_name>
<location>Daarzo!</location>
<description>JeugdSpeler excelsior Rotterdam O/13:1e divisie-follow #NF=miss #NFB-22C708B2</description>
<profile_image_url>http://a3.twimg.com/profile_images/1469644930/munch_2011_07_30_205323_normal.png</profile_image_url>
<profile_image_url_https>https://si0.twimg.com/profile_images/1469644930/munch_2011_07_30_205323_normal.png</profile_image_url_https>
<url></url>
<protected>false</protected>
<followers_count>106</followers_count>
<profile_background_color>C0DEED</profile_background_color>
<profile_text_color>333333</profile_text_color>
<profile_link_color>0084B4</profile_link_color>
<profile_sidebar_fill_color>DDEEF6</profile_sidebar_fill_color>
<profile_sidebar_border_color>C0DEED</profile_sidebar_border_color>
<friends_count>68</friends_count>
<created_at>Wed Oct 06 16:32:51 +0000 2010</created_at>
<favourites_count>2</favourites_count>
<utc_offset>3600</utc_offset>
<time_zone>Amsterdam</time_zone>
<profile_background_image_url>http://a0.twimg.com/images/themes/theme1/bg.png</profile_background_image_url>
<profile_background_image_url_https>https://si0.twimg.com/images/themes/theme1/bg.png</profile_background_image_url_https>
<profile_background_tile>false</profile_background_tile>
<profile_use_background_image>true</profile_use_background_image>
<notifications></notifications>
<geo_enabled>false</geo_enabled>
<verified>false</verified>
<following></following>
<statuses_count>9827</statuses_count>
<lang>en</lang>
<contributors_enabled>false</contributors_enabled>
<follow_request_sent></follow_request_sent>
<listed_count>0</listed_count>
<show_all_inline_media>false</show_all_inline_media>
<default_profile>true</default_profile>
<default_profile_image>false</default_profile_image>
<is_translator>false</is_translator>
</user>
<geo/>
<coordinates/>
<place/>
<contributors/>
</status>
</statuses>
BUILD SUCCESSFUL (total time: 2 seconds)

Kommandolinje klient, versjon 2 (jakarta commons)

{codecitation style="brush:java"}
package rest.jakarta;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;

public class RestJakarta {
public static void main(String[] args) {
HttpClient client = new HttpClient();
GetMethod method = new GetMethod("http://twitter.com/statuses/public_timeline.xml");
try {
int statusCode = client.executeMethod(method);
if (statusCode == HttpStatus.SC_OK) {
System.out.println(new String(method.getResponseBody()));
}
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
method.releaseConnection();
}
}
}

Gangen og resultatet i jakarta commons versjonen er det samme om i java.net versjonen. Fordelen er at Jakarta Commonst HTTP klienten gir oss en mer detaljert kontroll over HTTP tilkoblingene. For eksemel kan vi nå sjekke om vi har fått en HTTP 200 (if (statusCode == HttpStatus.SC_OK)), eller om noe har feilet underveis. Vi kan f.eks velge å gjøre noe dersom vi får en 404 (eller annen feilkode) på selve HTTP tilkoblingen.

Nettbasert varianten

I den nettbaserte varianten velger vi å spør etter rss representasjonen av de siste 20 statusoppdateringene. Husk at vi i første eksempelet ba om XML representasjon.

{codecitation style="brush:java"}

<%@page contentType="text/xml" pageEncoding="UTF-8"%><%@page import="java.io.BufferedReader, java.io.IOException, java.io.InputStreamReader, java.net.MalformedURLException, java.net.URL, java.net.URLConnection" %><%
try {
URL twitter = new URL("http://twitter.com/statuses/public_timeline.rss");
URLConnection tc = twitter.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
out.println(line);
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
%>

Som du kanskje merker er dette tilnærmet lik den første kodesnutten vi brukte (kommandolinje versjon 1). Vi åpner RSS representasjonen, og sender den til JSP standard utstrøm. Resultatet ser du i bildet under.

rest-jsp-twitter

Konklusjon

Jeg har igjennom tre eksempler vist hvor enkelt det faktisk er å hente ut data fra f.eks twitter sin API. Selv om eksemplene er veldig forenklet er de en god start for dine egne mashups. REST APIene gjør det også mulig å bruke klienter tilpasset mange forskjellige enheter (mobiler, brett, pcer, o.s.v). Ressursene ligger tilgjengelig for alle, og det er bare å spørre etter den representasjonen som passer deg og din klient best.

Legg gjerne igjen ideer eller eksempler på mashups i kommentarfeltet.

Tagged as : java rest

Comments

Tagged as : java rest