© 2011 IBA CZ, s.r.o.
Vývoj portletů – 2. část
František Hartman
Aleš Rybák
IBA CZ, s.r.o.
Vývoj portletů
Agenda
Komplexní portlety
Obsluha zdrojů (resource serving)
Meziportletová komunikace (IPC)
Sdílená session
Veřejné parametry (public render parameters)
Události (events)
Komplexní portlety
Více pohledů
Více akcí
CRUD
Administrační aplikace
Nastavení
Velké množství vstupních dat
Složitá aplikační logika
Více pohledů
Využít metodu doView() k rozdělování požadavků
na základě příchozích parametrů
podle uživatelského nastavení
Připravit zobrazovaná data v portletu
Využit JSP (nebo jinou technologii) k důslednému oddělení
view vrstvy
Více pohledů - ukázka
JSP:
Show list
…
Více pohledů - ukázka
Portlet:
public static final String PARAM_VIEW = “view”;
public static final String VIEW_DETAIL = “detail”;
public void doView(RenderReq., RenderResp.).. {
String view = req.getParameter(PARAM_VIEW);
if (VIEW_DETAIL.equals(view)) {
doViewDetail(request, response);
} else {
doViewMain(request, response);
}
}
protected void doViewDetail(RenderReq., RenderResp.).. {
...
}
protected void doViewMain(RenderReq., RenderResp.).. {
...
}
Více akcí
Využit metodu processAction() k rozdělování požadavků –
JSR-168
Využit anotace k rozdělování požadavků – JSR-286,
Java 5+
V akci
provést všechny změny stavu portletu
nastavit render parametry
odeslat události
Více akcí - ukázka
JSP:
“ />
…
Více akcí - ukázka
Portlet:
...
@ProcessAction(name=ACTION_SEARCH)
public void actionSearch(ActionRequest request, ActionResponse response) throws
PortletException, IOException {
...
response.setRenderParameters(request.getParameterMap());
}
@ProcessAction(name=ACTION_ADD_TO_CART)
public void actionAddToCart(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
...
}
Konstanty, nastavení, pomocné metody
Programové konstanty – PortletNameConstants (např.
CatalogConstant)
Nastavení
Init parameters
portlet.xml
web.xml
Preferences
Pomocné metody
Odstranění duplikace kódu
Vede ke snadnější udržovatelnosti
Dědičnost vs. Util třídy
Použití MVC
V MVC je
Portlet = Controller
JSP = View
Bussiness vrstva (DTO) = Model
Velké množství vstupních dat
Validace není součástí specifikace
Zvážit použití MVC rámce, zjednoduší:
Validaci dat
Převod dat z formuláře na objekty
Složitá aplikační logika
Patří do modelu
Portlet by měl obsahovat pouze logiku UI
Komplexní portlety
Velmi složitý portlet může naznačovat špatný návrh a
portletovou dekompozici
Zkontrolovat návrh aplikace
Různé portlety pro různé role
Portlety podle případu užití
Zkontrolovat duplikaci kódu
Zvážit možnosti zjednodušení či rozložení funkcionality do
více portletů
Zvážit využití MVC rámce
Poskytování statických zdrojů
PortletResponse.encodeURL()
Nemusí vygenerovat validní URL
Vyšší výkon – nedochází k zpracování portálem
Doporučený způsob pro statický obsah v JSR-168
Cachované resourceURL v JSR-286
Poskytování dynamických zdrojů
JSR-168
Nemožné získat pouze fragment kódu nebo
dynamická binární data
Řešení – servlet
Problémy s autentizací
Problémy se získáváním dat z portletu
(preference, uživatel atd.)
JSR-286
Rozhraní ResourceServingPortlet s metodou
serveResource()
Klient může posílat požadavky na neagregovaná
data
Binární data (obrázky, dokumenty, ...)
Serializovaná data (JSON, …)
HTML fragmenty
Často také ve spojení s technologií AJAX
Sekvence požadavků při poskytování zdroje
Dynamické zdroje - implementace
Metoda serveResource()
Neměla by měnit stav portletu (databáze), pokud
je volána metodou GET
ResourceRequest
getResourceID()
getCacheability()
FULL, PAGE, PORTLET
ResourceResponse
setContentType()
getWriter()
getPortletOutputStream()
Dynamické zdroje - ukázka
JSP:
…
Portlet:
@Override
public void serveResource(ResourceRequest request, ResourceResponse response) throws
PortletException, IOException {
String resourceID = request.getResourceID();
if (RESOURCE_QUERY.equals(resourceID)) {
...
} else {
super.serveResource(request, response);
}
}
Meziportletová komunikace (IPC)
JSR-168
Nemá standardizovanou cestu pro
meziportletovou komunikaci
Řešení
Sdílení dat v „application scope“ session
JavaScript
Databáze
Proprietární řešení
JSR-286
Veřejné parametry (public render parameters)
Události (events)
(Cookies)
Session – application scope
Využívá se http session
PORTLET_SCOPE
APPLICATION_SCOPE
Sdílení dat v rámci portletové aplikace
Nelze sdílet mezi aplikacemi
Změny provádět během zpracování akcí či událostí
Pozor na změny dat session v render fázi
Pozor na kolize jmen
Public render parameters
Nejjednodušší standardní metoda meziportletové
komunikace
Parametry se definují v deskriptoru portlet.xml
Parametr je definován jako veřejný
Pro každý parametr je nutné definovat jedinečné
jméno
Pro portlet se definuje který z veřejných
parametrů využívá
Veřejné parametry jsou dostupné ve všech částech
životního cyklu požadavku
Pouze řetězcové hodnoty
Public render parameters - ukázka
portlet.xml:
http://pv230.ibacz.eu/
param1
p1
…
param1
Události - events
Události umožňují portletům reagovat na akce nebo změny
stavu, které nesouvisí přímo s interakcí uživatele s
portletem
Portlety mohou reagovat na různé události a měnit svůj stav
Např. událost přidání položky do košíku
Události mohou být vysílány jak portálem tak portlety
Zpracování událostí probíhá před render fází
Události - events
Události - events
Události jsou navrženy podle vzoru Producer – Listener
Portlety mohou vytvářet události
Portlety mohou události přijímat (portlet musí
implementovat rozhraní EventPortlet)
Události se mohou řetězit
Událost je objekt
Události je možné posílat mezi portlety různých portletových
aplikací
Pozor na umístění třídy události – možné
problémy s classloaderem
Události - events
Nastavení se provádí v deskriptoru portlet.xml
Každá událost má jedinečné jméno
Pro portlety se nastavuje, které události vysílá a
které přijímá
Velmi mocné
Mohou zvýšit složitost projektu
Jedná se prakticky o interface, který portlet
poskytuje a k němuž mohou přistupovat
portlety třetích stran
Události - events - ukázka
portlet.xml:
http://pv230.ibacz.eu/
event1
java.lang.String
…
event1
event1
Události - events - ukázka
portlet:
@ProcessAction(name=ACTION_ADD_TO_CART)
public void actionAddToCart(ActionRequest request, ActionResponse response) throws
PortletException, IOException {
response.setEvent("event1", "event value");
}
@ProcessEvent(name="event1")
public void processEvent1(EventRequest request, EventResponse response) throws
PortletException, IOException {
Event e = request.getEvent();
String value = (String) e.getValue();
...
}
Události vs. Veřejné parametry
Veřejné parametry
Výhody
Jednoduché a účinné
Pracuje s renderURL
(záložky, caching)
Použití
Zobrazení příbuzných
informací v několika
portletech na stejné
stránce
První volba pro IPC
Co nedělat?
Nastavit všechny parametry
jako veřejné
Události
Výhody
Velmi mocné
Volnost v jejich použití a možnost
řetězení
Použití
Když nestačí veřejné parametry
K propagování stavu napříč portlety
Co nedělat?
Používat události jako message
system