Prosegue la trattazione della Portlet API: questo mese affrontiamo alcune interessanti caratteristiche utili per la realizzazione di un portale e introduciamo quelle che che dovrebbero essere le nuove caratteristiche della prossima release (JSR 286, ovvero la Portlet API 2.0), di prossima pubblicazione.

Portlet TAG lib

Una portlet, come ogni altro componente che deve interagire con il client web (servlet, pagine JSP), deve produrre in risposta a una request del codice HTML che verrà poi renderizzato dal browser. Come si è avuto modo di vedere nelle puntate precedenti a parte la tecnica che prevede la stampa riga per riga del codice di risposta, una tecnica certamente più raffinata e potente è quella che prevede l'inclusione di pagine JSP nella risposta da inviare al client. Per poter gestire in modo ancora più potente e automatizzato tali pagine, a partire dalla relese JSP 1.1 è possibile utilizzare librerie di tag custom che consentono sia di risparmiare tempo di stesura del codice, sia di automatizzare alcune operazioni ripetitive. Anche nel mondo delle portlet è possibile sfruttare questa possibilità tanto che la specifica impone che ogni portlet container di fornire una implementazione della Portlet Tag Library. Per utilizzare la tag library nella JSP che è inclusa nella portlet è necessario per prima cosa definire la libreria tramite apposito URI

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<%@ taglib uri="portlet.tld" prefix="portlet" %>... <center> <font size="6" color="green">Portlet 2 - Page 1</font><BR> <p><p> Portlet Webflow Test: <p> <a href="<portlet:createWebflowURL event="switch"/>">Next Page</a> <p> </center>

<portlet:actionURL windowState="maximized" portletMode="edit">
	<portlet:param name="action" value="doSomeAction">
</portlet:actionURL>

protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws ... response.setContentType("text/html");

String userName = (String)request.getPreferences().getValue("userName",null);

if (userName != null) response.getWriter().println("Ciao" + userName);

else response.getWriter().println("Vai in edit mode e inserisce il tuo username");

} public void processAction(ActionRequest aRequest, ActionResponse aResponse) throws ... String userName = aRequest.getParameter ("userName");

PortletPreferences pref = aRequest.getPreferences();

pref.setValue("userName",userName);

pref.store();

actionResponse.setPortletMode(PortletMode.VIEW);

}

<portlet> <expiration-cache>300</expiration-cache> </portlet>

public class SleepingBeautyPortlet extends GenericPortlet { public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {

response.setContentType("text/html");

PrintWriter writer = response.getWriter(); // stampa la data e ora corrente String format = "EEE d MMM yyyy, hh:mm:ss aaa";

SimpleDateFormat df = new SimpleDateFormat(format);

writer.write("<h3>Ora e Data </h3>");

writer.write(df.format(new Date()).toString());

writer.write("<br>Clicca <A href="+response.createActionURL().toString()+">qui</a> per risvegliare la portlet");

} public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException{

System.out.println("processAction(): enter");

}

}

response.setContentType("text/html");

	PrintWriter writer = response.getWriter();

	ResourceURL resURL = response.createResourceURL();

	resURL.setResourceID("image");

// stampa HTML con il link all'immagine da inviare al browser
	writer.println("<IMG src=\"" + resURL+ "\" >");
// altre operazioni di rendering
}

Questa tecnica, oltre a essere piuttosto scomoda per il client (l'utente deve eseguire un ulteriore request per ottenere l'immagine) è poco elegante e piuttosto rudimentale anche dal punto di vista del programmatore (in epoca di Web 2.0, stampare HTML è una operazione che nessun neo-assunto vuole fare). Ecco come, con la JSR 286 si potrà ottenere questo risultato in modo certamente più elegante: la nuova GenericPortlet offre infatti un nuovo metodo da implementare che potrebbe essere "riempito" in questo modo:

public void serveResource(ResourceRequest resRequest, ResourceResponse resResp)

throws PortletException, IOException {

resResp.setContentType("image/png");

	byte[] b = getImage("MyImage.PNG");
// Returns image bytes
	resResp.getPortletOutputStream().write(b);

[286] JSR 286: Portlet Specification 2.0 http://jcp.org/en/jsr/detail?id=2867