SPA-portletin palvelinpään toteutus

SPA-portletin palvelinpuolen Java-koodi on yksinkertainen. Mitään MVC-mallin mukaista portlettia (esim. tavanomainen MVCPortlet) ei tarvita, koska MVC-arkkitehtuurimallin kontrolleri on clientilla, eli Javascript-koodi on kontrolleri. SPA-portlettiluokka on MVC-portlettiluokkaa merkittävästi yksinkertaisempi kahdessa mielessä:
1. Portletti huolehtii vain ensimmäisen JSP-sivun avaamisesta. Clientin Javascript-koodi huolehtii sivuvaihtoista.
2. Sovelluslogiikkaa ei ole enää action-metodeissa. Action-metodeja ei tarvita lainkaan. Ajax-kutsut käsitellään serveResource-metodissa.

Seuraavat periaatteet toimivat, olipa portletin käyttöliittymässä käytetty joko Angular- tai jQuery-kirjastoa. Esitämme tässä vain periaatteet, yksityiskohdat löytyvät kirjallisuudesta tai Liferayta käsitteleviltä nettisivuilta.

Portlettiluokan voi toteuttaa suoraan yksinkertaisesta GenericPortlet-luokasta. Parempi ratkaisu on kuitenkin tehdä oma luokka GenericPortlet-luokasta perien, toteuttaa siinä muutama perustoiminto ja käyttää tätä yleistä template-luokkaa edelleen sovelluksen portletin yläluokkana. Näin toimien ei sovelluskohtaisessa portletluokassa tarvitse toteuttaa kuin serveResource-metodi, joka käsittelee kaikki clientilta tulevat Ajax-kutsut. Periaate on yksinkertainen ja sitä voidaan toistaa poikkeuksetta. Tällaiset periaatteet ovat seppien mieleen erityisesti.

Alla perusluokka SPAPortlet, jossa toteutetaan perustoiminnot:

public class SPAPortlet extends GenericPortlet {...}

Luokassa SPAPortlet toteutettavia perustoimintoja ovat:
– viewTemplate-määrityksen lukeminen liferay-portlet.xml -tiedostosta (getInitParameter(”view-template”);)
– doView metodin toteuttaminen, niin että portlettiin tultaessa avataan viewTemplate-parametrin osoittama aloitussivu.
– portletin nimiavaruuden lukeminen jonkin luokan staattiseksi tiedoksi. Tämä luetaan doViewissa: renderRequest.getNamespace()

Viimeinen epästandardi kohta tarvitaan, koska nimiavaruus on luettava skripletissa tuosta staattisesta tiedosta, kun ladataan dynaamisesti SPA-portletin JSP-sivuja. Nyt sovelluskohtainen portletluokka voidaan määritellä pelkistetysti niin, että siinä on jokaiselle Ajax-toiminnoille oma tunniste ja serveResource-metodi:

public class SovellusPortlet extends SPAPortlet 
{
   public static final String GET_ALL = "getAll";
   public static final String GET_ROW = "getRow";

   public void serveResource(ResourceRequest req, ResourceResponse resp)
                             throws PortletException, IOException {...}
}

JSP-aloitussivulla, eli viewTemplate-vakion osoittamalla sivulla, nämä vastaavat Ajax-toiminnot määritellään käytettäväksi Javascriptissa:



Näiden käyttö Javascriptissa esitetään seuraavissa blogeissa. Ajax-toiminnon tunnus kiertää siis viestikapulan lailla Javasta Javascriptiin.

ServeResource-metodin request-olion sisältämän portletin syötteen lukeminen voi olla ongelma, Liferayn versiosta riippuen. Syöte kirjoitetaan clientilla JSON-olioksi. Tämä luetaan clientilla käytetystä Javascript-kirjastosta riippuen eri tavalla portletkoodissa:
– jQuery: lue syöte parametri kerrallaan HttpServletRequest-oliosta getParameter-metodilla. Tämä olio puolestaan saadaan ResourceRequest-oliosta.
– Angular: lue syöte yhtenä merkkijonona, joka muutetaan edelleen JSONObject-olioksi. Merkkijono luetaan rivi kerrallaan BufferedReader-oliolla. Tämä olio saadaan ResourceRequest-olion getReader-metodin paluuarvona.

Angularin menetelmä edellä toiminee muidenkin Javascript-kirjastojen kanssa, koska se on yleinen tapa. Toimivuus pitää tutkia tapauskohtaisesti. Parametrien luvussa näkyy portletin ja servletin sukulaisuussuhde. Nämä molemmat edelläkuvatut tavat muistuttavat servletissa käytettäviä sisääntuloparametrien lukutekniikoita. Samankaltaisuus jatkuu paluuarvon tulostamistavassa.

Portlettiluokan (edellä SovellusPortlet) muuhun toteutukseen liittyen olemme keränneet seuraavat neuvot:
– Javascriptissa oma JSON-formaatti on luontevin. Ajax-kutsujen parametrit tulevat portletluokkaan yhdessä Json-oliossa ja paluuarvo palautetaan clientille samoin.
– Ajax-toiminto tunnistetaan edellä kuvattujen tunnisteiden kautta. Request-olion getResourceId-metodi palauttaa Ajax-toiminnon tunnisteen.
– Jokaiselle Ajax-toiminnolle tehdään serveResource-metodiin oma if-haara. Jos koodia tulee useita rivejä, niin selvyyden vuoksi nämä rivit kirjoitetaan erilliseen luokkaan, ja kutsutaan if-haarassa kyseisen luokan oliota.
– serveResource-metodin if-elseif-else-valintarakenne voi olla hyvin pitkäkin ongelmitta, koska jokainen valinta sisältää itsenäisen toiminnon, joilla on yhteiset alku- ja lopputoimet serveResource-metodissa. Tämä ei siis ole huonoa spagettikoodia, eikä sitä ei voi järkevästi pilkkoa.
– Virhekäsittely on mietittävä huolella niin, että kaikki virheet otetaan kiinni ja niistä saadaan tulostus lokille sekä kutsuvalle clientille. Clientti lukee virhetilanteessa virhekuvauksen Ajax-kutsun JSON-paluuarvosta. On tärkeää, että Ajax-kutsut palauttavat aina jonkin tuloksen käyttöliittymään, olipa toiminto onnistunut tai ei. Virhetilanteen jatko on MVC-mallissa kontrollerin asia, eli se käsitellään Javascriptissa.
– JSON-paluuarvon kirjoitus merkkijonona on vakiotoimenpide käyttäen PrintWriter-oliota.

Seuraavassa blogissa tarkastellaan palvelurajapinnan ja datan käyttöä portletluokassa.

Scroll to Top