Java EE 6 ja RESTful Web Services Osa 2

Artikkelisarjan ensimmäisessä osassa tutustuttiin REST web service tyyliin uudella Java EE 6 alustalla. Ensimmäinen osa esitteli tavanomaisen Hello World tasoisen esimerkin jossa palautettiin ääri-yksinkertainen XML tiedosto. Entäpä miten REST taipuu monimutkaisempiin tarpeisiin kuten esim. tuotedokumentin palauttamiseen?

Parasta on hyödyntää JAXB tekniikkaa. Sensijaan että paluutyypiksi laitetaan String, kannattaakin tehdä XML schema joka määrittää haluamasi XML siirtorakenteen, generoida siitä Java-tyypit, ja käyttää näitä Java-tyyppejä paluuarvoina. Tässä esimerkki suht yksinkertaisesta tuoteschemasta:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xs:schema xmlns:xs=”http://www.w3.org/2001/XMLSchema&#8221; elementFormDefault=”qualified” attributeFormDefault=”unqualified”>
<xs:element name=”items”>
<xs:complexType>
<xs:sequence>
<xs:element name=”item” type=”item” maxOccurs=”unbounded”/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name=”item”>
<xs:sequence>
<xs:element name=”id” type=”xs:int”/>
<xs:element name=”name” type=”xs:string”/>
<xs:element name=”description” type=”xs:string”/>
<xs:element name=”price” type=”xs:string”/>
<xs:element name=”publishDate” type=”xs:date”/>
</xs:sequence>
</xs:complexType>
</xs:schema>

Yllä on tyypillinen xml rakenne jossa on juurielementti, jonka alla on alielementtejä, joiden alla on elementteihin koodattua tietoa. Anna tämä schema JAXB työkalulle ja siitä generoituu luokat Items, Item (sekä ObjectFactory). Tämän jälkeen voit koodata REST web service metodin tähän tapaan:

@GET

public Items getItem(@QueryParam(value = ”id”) int id) {

// here we would query database for item id 1 but

// to make the point we instead just generate same item

// everytime and ignore the parameter

Items items = new Items();

Item item = new Item();

item.setId(1);

item.setName(”Lawnmower”);

item.setDescription(”Useful tool to keep your lawn tidy”);

item.setPrice(”1000 eur”);

items.getItem().add(item);

return items;

}

Kun kutsut tätä koodia selaimesta osoitteella http://localhost:21136/RESTDemo/resources/items?name=Arto – saat tämän näköisen XML dokumentin palkaksesi:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”>
<items>
<item>
<id>1</id>
<name>Lawnmower</name>
<description>Useful tool to keep your lawn tidy</description>
<price>1000 eur</price>
</item>
</items>

Mielenkiintoista? REST hyväksyy paluuarvoiksi myös JAXB mäpätyn objektin – koska se tietää miten se muutetaan XML muotoon. Ylläoleva esimerkki luo itse Items ja Item oliot, mutta aito koodi tietysti pujahtaa tietokantaan hakemaan nämä – esim. kätevästi JPA rajapintaa ja Entity Object:eja hyödyntäen.

Suosittelen lähtemään liikkeelle Schema määrityksestä – koska silloin ratkaisu tulee olemaan XML schema ehdoilla tehty, ei Java olioiden ehdoilla. Schemat ja XML rajapinnat ovat kuitenkin jotain jonka kanssa tulet luultavasti elämään pitkänkin aikaa – sitävastoin oliorakenteet ja palvelimen sisäinen logiikka voi vapaasti elää ja hengittää.

Debugging: Voit saada ilmoituksen tähän tapaan:

SEVERE: A message body writer for Java type, class fi.tieturi.services.hello.Item2, and MIME media type, application/xml, was not found

Tämä tarkoittaa että JAXB annotaatioita ei ole luokkaan tehty eli yrität palauttaa olion joka ei ole JAXB mäpätty ja näin ei ole tietoa miten se saadaan XML muotoon. Huomaa myös että voit palauttaa vain schema päätason olion eli juurielementin, et sisäisiä pikkutyyppejä joita ei ole suunniteltu päätasolla käytettäviksi.

Muita mielenkiintoisia piirteitä:

Huomaa että tehdessäsi lisää metodeita luokkaan voit määrittää aina path osuuden uudestaan. Metoditason path määritys käytännössä lisätään luokkatason path määritykseen kun haet resurssia. Jos haluat esim. uuden metodin tähän tapaan:

@GET

@Path(”item2”)

public Items getItem2() {

Items items = new Items();

return items;

}

Voit kutsua sitä selaimesta tällaisella URL osoitteella: http://localhost:21136/RESTDemo/resources/items/item2

Näin on mahdollista tehdä samaan REST palveluun useitakin eri hakumetodeita, esim. hae kaikki tuotteet, hae yksi tuote, jne.

Toinen mielenkiintoinen jippo mitä voit tehdä on siirtyä XML koodauksesta JSON koodaukseen. JSON tulee sanoista JavaScript Object Notation ja on XML:ää hitusen tehokkaampi ja suoraviivaisempi tapa siirtää olioita verkon yli. Java EE 6 Rest antaa mahdollisuuden muuttaa luokan tai yksittäisen metodin koodaustapa JSON muotoon tähän tapaan:

@Produces(MediaType.APPLICATION_JSON)

Paluutyyppien tulee silti edelleen olla JAXB mäpättyjä objekteja. Nyt osassa 1 esitellyn metodin palauttama dokumentti olisikin xml:n sijaan tällainen:

{”item”:{”id”:”1″,”name”:”Lawnmower”,”description”:”Useful tool to keep your lawn tidy”,”price”:”1000 eur”}}

Siinä on edelleen sama data, mutta nyt tiiviimmässä paketissa. Huomaa että koska annotaatio voidaan tehdä metoditasolla, voit halutessasi tarjota samoista metodeista erikseen sekä XML että JSON vaihtoehdot sen mukaan mitä asiakaspää osaa helpoimmin käsitellä.

Tässä taas hetkeksi sulateltavaa, palaamme taas asiaan jatkossa.

Mainokset

Vastaa

Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:

WordPress.com-logo

Olet kommentoimassa WordPress.com -tilin nimissä. Log Out / Muuta )

Twitter-kuva

Olet kommentoimassa Twitter -tilin nimissä. Log Out / Muuta )

Facebook-kuva

Olet kommentoimassa Facebook -tilin nimissä. Log Out / Muuta )

Google+ photo

Olet kommentoimassa Google+ -tilin nimissä. Log Out / Muuta )

Muodostetaan yhteyttä palveluun %s