Portale und Portlets (1) – Grundlagen

Portlets und JSP

Die ersten Beispiele von Portlets direkt mit der Portlet-API erinnern natürlich zunächst an die frühen Anfänge der Servlet-Programmierung. Html-Markup wird in der Java-Klasse implementiert. Dies ist natürlich nicht gerade eine moderne Weise der Markup-Generierung und Seitenerzeugung. In der Portlet-Spezifikation ist daher eine Verwendung und Integration von JavaServer Pages (JSP) vorgesehen. Erster Ansprechpartner für den Portlet-Container bleibt zunächst eine Portlet-Klasse. Diese kann für die Markup-Erzeugung an eine JSP delegieren. Damit lässt sich sehr schön ein Model-View-Controller-Muster umsetzen. Die Portlet-Klasse bildet den Controller, der für die Anzeige an die zuständige JSP (View) delegiert.

Listing 3: Portlet mit Dispatching an ein JSP-Fragment
protected void doView(RenderRequest request, RenderResponse response) 
      throws PortletException, IOException {
   PortletContext context = getPortletContext();
   PortletRequestDispatcher dispatcher 
      = context.getRequestDispatcher( "/simple.jsp" );
   dispatcher.include( request, response );
}
Listing 4: JSP-Fragment für ein Portlet

Ihr Name:

In Listing 4 wird das Markup in einer JSP erzeugt. Dabei wird eine spezielle Tag Library, die Portlet Taglib, verwendet. Mit der Portlet Tag Library kann auf Portlet-spezifische Funktionalität zugegriffen werden. So erzeugt das Tag eine Url, mit der auf eine Action-Phase verwiesen wird. Damit wird im Portlet bei Abschicken des Formulars die processAction-Methode ausgeführt, anschließend wird die doView-Methode aufgerufen und das neue Markup generiert. Ist eine entsprechende processAction-Methode in der Portlet-Klasse nicht implementiert, wird eine PortletException geworfen.

Window States und Portlet Modes

Portlets weisen zwar viele Ähnlichkeiten zu Servlets auf, es gibt jedoch auch sehr deutliche Unterschiede. Während eine Webanwendung basierend auf der Servlet-Technologie im Normalfall immer Markup erzeugt, das seitenfüllend ist, haben Portlets nur einen bestimmten Bereich einer Portalseite zur Verfügung. So kann mit den Portlet Window Controls der Platzbedarf eines Portlets beeinflusst werden. Durch die Spezifikation sind die Window States minimized, maximized und normal vorgegeben. Wie genau diese drei States umgesetzt sind, bleibt dem Portal überlassen. In der Regel ist im minimized State lediglich der Fenstertitel zu lesen, alles andere wird ausgeblendet. Bei maximized werden alle anderen Portlets der Seite minimiert und dem betreffenden Portlet der maximal verfügbare Platz zugestanden. Normal ist der standardmäßige, übliche Platzbedarf, der meist durch ein Portal-Skin oder Theme vorgegeben wird.

Abb. 3: Minimierte Fenster in iGoogle

Eine weitere Besonderheit von Portlets ist der Portlet Mode. Standardmäßig befinden sich Portlets immer im View-Mode: Das Portlet stellt sich dar und kann Aktionen verarbeiten. Soll das Portlet jedoch konfiguriert werden (z.B. die Eingabe einer Postleitzahl für ein Wetter-Portlet), kann diese Einstellung im Edit-Modus vorgenommen werden. Für die Anzeige der Wettervorhersage wird für einen Benutzer das Portlet so konfiguriert, dass er die Anzeige für seine Stadt nach dem Login in das Portal erhält. Dies ist übrigens auch ein sehr schönes Beispiel für Personalisierung: Jeder Benutzer kann seine Portlets auf seine Bedürfnisse hin anpassen und konfigurieren.
Auf Window States und Portlet Modes kann (und sollte natürlich) programmatisch reagiert werden. Beispielsweise kann in der doView-Methode abgefragt werden, welchen Platzbedarf man ausfüllen darf. Über den Aufruf request.getWindowState() wird ermittelt, in welchem Window State sich das Portlet aktuell befindet. Daraufhin kann ein entsprechendes Markup erzeugt werden. Für die Portlet Modes bietet das GenericPortlet bereits Methoden für die Standard-Portlet-Modes an. Es kann eine doView- oder eine doEdit-Methode überschrieben werden, die das entsprechende Markup zurückliefert. Zusätzlich muss in der portlet.xml angegeben werden, dass auch der Edit-Modus verfügbar ist (der View-Modus ist obligatorisch für alle Portlets).

Portlet vs. Portlet-Applikation

Häufig werden die Begriffe Portlet und Portlet-Applikation synonym verwendet. Dies ist jedoch nicht korrekt. Ein Portlet bezeichnet eine Klasse, die das Portlet-Interface implementiert und somit als Portlet fungieren kann. Unter einer Portlet-Applikation wird das gesamte Webprojekt verstanden, inklusive Deployment-Deskriptoren und sonstigen Ressourcen. Eine Portlet-Applikation wird in der Regel als war-Datei deployt. Innerhalb einer Portlet-Applikation kann es durchaus mehrere Portlets geben, die alle in der portlet.xml definiert sein müssen.

Render-Parameter

Auf die Unterscheidung von Render- und Action-Phase wurde bereits hingewiesen. Sie haben in den Beispielen gesehen, dass beide Phasen unabhängig voneinander aufgerufen werden können. Beide Phasen können basierend auf einer Benutzeraktion (z.B. Klick eines Buttons) nacheinander aufgerufen werden. Es kann jedoch auch sein, dass lediglich die Render-Phase angestoßen wird. Wird allerdings eine Aktion verarbeitet, auf die in der folgenden Render-Phase reagiert werden soll, müssen eventuell Informationen von der Action-Phase in die Render-Phase gelangen. Wichtig für das Verständnis der Portlet-Technologie ist, dass beide Phasen als absolut getrennt betrachtet werden müssen. Zwar gibt es in der Action-Phase ein ActionRequest- und ein ActionResponse-Objekt. Aber Attribute, die über Methoden wie setAttribute gesetzt werden, stehen nicht in der Render-Phase in den RenderRequest- und RenderResponse-Objekten zur Verfügung. Es muss somit ein Mechanismus gefunden werden, um Werte von der Action-Phase in die Render-Phase zu transportieren. Eine Möglichkeit wäre sicherlich (wenn auch eine sehr aufwändige), die Daten in der Action-Phase in die Datenbank zu schreiben. In der Render-Phase könnten diese Daten gelesen und angezeigt werden. Eine weitere Möglichkeit wäre ein Austausch der Daten über die Session. Darauf wird im nächsten Abschnitt eingegangen. Die einfachste Möglichkeit jedoch ist die Verwendung von so genannten Render Parametern. Über den Aufruf von actionResponse.setRenderParameter(„yourname“, „Max Müller“) wird in der Action-Phase ein Parameter für die folgende Render-Phase eingestellt. In der Render-Phase kann über request.getParameter(„yourname“) darauf zugegriffen werden. Render-Parameter sind somit ein sehr einfaches Konstrukt, um zwischen den Phasen Werte zu transportieren. Allerdings haben Render-Parameter auch Einschränkungen. Es können lediglich Strings als Render Parameter gesetzt werden bzw. String Arrays. Zudem kann nur das gleiche Portlet die Parameter lesen. Eine Übermittlung der Render-Parameter an andere Portlets ist nicht möglich (hier liefert der JSR-286 mit Public-Render-Parametern eine entsprechende Erweiterung).

Portlet-Session

Daten, die während einer Benutzersitzung (Session) gehalten werden sollen, können natürlich auch in der Portlet-Welt in einer Portlet-Session gespeichert werden. Eine Portlet-Session erhält man z.B. in einer Action-Phase über renderRequest.getPortletSession(). Die Portlet-Session hat gegenüber einer Servlet-Session ein paar Besonderheiten. Zum einen hat jedes Portlet seine eigene PortletSession. Dies bedeutet, dass auch, wenn mehrere Portlets auf einer Portalseite angeordnet sind, jedes Portlet seine eigene Portlet-Session hat. Es gibt jedoch einen Sonderfall, wenn nämlich mehrere Portlets in einer Portlet-Applikation enthalten sind. Diese können über den Application-Scope der Portlet-Session Daten austauschen. So kann in einem Portlet über portletSession.setAttribute(„fullname“, fullname, PortletSession.APPLICATION_SCOPE) ein Wert in den Application-Bereich der Portlet-Session eingestellt werden und in einem anderen Portlet über portletSession.getAttribute(„fullname“, PortletSession.APPLICATION_SCOPE) darauf zugegriffen werden. Dieses Verfahren bildet häufig die Basis für IPC (Inter Portlet Communication). Es ist das einzige Verfahren, das mit dem JSR-168 möglich war. Zwar gab es in einigen Portalprodukten noch andere APIs für einen Informationsaustausch unter Portlets, diese waren jedoch proprietär und nicht standardkonform. Auch an dieser Stelle liefert der JSR-286 zusätzliche Möglichkeiten.

Fazit

Portale bieten heutzutage einen mächtigen Satz an Funktionen, um anspruchsvolle Webanwendungen zu realisieren, ohne dabei grundlegende Anforderungen selbst umsetzen zu müssen. Mit den Vorteilen einer standardisierten Portlet-Technologie können zudem sehr einfach einzelne Portlets für ein Portal entwickelt werden. Die Portlet-Entwicklung lehnt sich dabei stark an die Servlet-Technologie an, sodass ein Einstieg für Webentwickler sehr einfach gelingen kann.

Andy Bosch ist freier Berater und Trainer für die Technologien Portlets und JavaServer Faces. Er ist Mitglied der Expert Group des JSR-301 sowie Betreiber der Plattformen www.jsf-forum.de und www.jsf-portlets.net. Zudem ist er Vorstand von SENS (Software Experts Network Stuttgart, www.SoftwareExperts.de).

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.