Die Koordinierung zwischen Portlets ist eine sehr häufige Anforderung. Ein Beispiel für die gemeinsame Nutzung von Informationen durch Portlets wäre ein Wetter-Portlet, das die Wetterinformationen einer Stadt anzeigt, und ein Karten-Portlet, das den Standort der Stadt anzeigt. Da beide Portlets dieselbe Postleitzahl für einen Benutzer verwenden, sollten die Portlet-Container einen Mechanismus vorsehen, der es den Portlets ermöglicht, die Postleitzahl gemeinsam zu nutzen.
Vor JSR 286 war die Unterstützung für die Kommunikation zwischen Portlets eher minimal und der Informationsaustausch zwischen verschiedenen Portlets wurde hauptsächlich über anwendungsspezifische Sitzungsobjekte oder herstellerspezifische APIs abgewickelt. Beide Methoden waren recht problematisch, da bei der ersten die Eindeutigkeit des Sitzungsattributs über eine komplexe Anwendung hinweg ein Problem darstellte und bei der zweiten die Portabilität des Portlets beeinträchtigt wurde. Um die Koordination zwischen Portlets zu ermöglichen, führt die Java Portlet Specification v2.0 (JSR 286) die folgenden Mechanismen ein:- öffentliche Render-Parameter, um den Render-Status zwischen Portlets zu teilen.
- Portlet-Ereignisse, die ein Portlet empfangen und senden kann.
In JSR 286 können die von einem Portlet weitergegebenen Renderparameter den Rendermethoden anderer Portlets zur Verfügung gestellt werden. Dies wird in der folgenden Abbildung erläutert.
Um die Koordination von Rendering-Parametern mit anderen Portlets innerhalb derselben Portlet-Anwendung oder über Portlet-Anwendungen hinweg zu ermöglichen, kann das Portlet in JSR 286 Portlets öffentliche Rendering-Parameter in seinem Deployment-Deskriptor unter Verwendung des public-render-parameter-Elements im Portlet-Anwendungsabschnitt deklarieren. Im Portlet-Abschnitt kann jedes Portlet die öffentlichen Render-Parameter angeben, die es über das Element supported-public-render-parameter gemeinsam nutzen möchte. Das Element supported-public-ender-parameter muss auf den Bezeichner eines öffentlichen Renderparameters verweisen, der im Portlet-Anwendungsabschnitt in einem public-render-parameter-Element definiert ist. Das Portlet sollte den definierten Bezeichner des öffentlichen Render-Parameters in seinem Code verwenden, um auf den öffentlichen Render-Parameter zuzugreifen.
Schauen wir uns an, wie es funktioniert.
Betrachten Sie das folgende Beispiel.
1. Legen Sie die öffentlichen Render-Parameter auf der Ebene der Portlet-Anwendung fest.
id1 x:param1 id2 x:param22. Geben Sie im Abschnitt Portlet den Rendering-Parameter an, den das Portlet gemeinsam nutzen möchte.
PortletA id1 id2 PortletB id1 PortletC id2Die oben deklarierten öffentlichen Render-Parameter werden wie in der Abbildung unten erklärt verarbeitet.
Da die öffentlichen Render-Parameter in der URL kodiert sind, sind die Werte, die von den Portlets gemeinsam genutzt werden können, auf String und String-Arrays beschränkt. Da öffentliche Rendering-Parameter nur in der Rendering-Methode verfügbar sind, sollten die von den Portlets gemeinsam genutzten Informationen für das Rendering der Ansicht und nicht für die Verarbeitung der gemeinsam genutzten Informationen verwendet werden.
Portlet-Ereignisse
Portlet-Ereignisse können als Ergebnis einer Benutzerinteraktion mit anderen Portlets erzeugt werden. Das Portlet-Ereignismodell ist ein lose gekoppeltes, vermitteltes Modell, das die Erstellung von Portlets als eigenständige Portlets ermöglicht, die zur Laufzeit mit anderen Portlets verkabelt werden können. Portlet-Programmierer sollten daher keine spezifischen Annahmen über die Umgebung der Portlets machen, mit denen sie zusammenarbeiten. Die Art und Weise, wie verschiedene Portlets miteinander verkabelt werden, hängt von der jeweiligen Portal-Implementierung ab. Ein Beispiel, bei dem ein Portlet den Empfang von Ereignissen anbieten möchte, sind Zustandsänderungen, die durch einfache Benutzerinteraktionen ausgelöst werden, z.B. das Hinzufügen eines Artikels zu einem Einkaufswagen. Wenn Sie dies als Ereignis für andere Portlets anbieten, können diese das Hinzufügen von Artikeln zum Einkaufswagen auf der Grundlage der Benutzerinteraktionen in diesen Portlets auslösen.
EventPortlet-Schnittstelle
Um Ereignisse empfangen zu können, muss das Portlet die EventPortlet-Schnittstelle im javax.portlet-Paket implementieren. Der Portlet-Container ruft die processEvent-Methode für jedes Ereignis auf, das mit einem EventRequest- und einem EventResponse-Objekt an das Portlet gerichtet ist.
Ereignisse werden vom Portal-/Portlet-Container an ein bestimmtes Portlet-Fenster in der aktuellen Client-Anfrage gerichtet. Ereignisse sind ein Lebenszyklusvorgang, der vor der Rendering-Phase stattfindet. Das Portlet kann über die setEvent-Methode während der Aktionsverarbeitung Ereignisse ausgeben, die vom Portlet-Container nach Abschluss der Aktionsverarbeitung verarbeitet werden. Als Folge der Ausgabe eines Ereignisses kann das Portlet optional Ereignisse von anderen Portlets oder Container-Ereignisse empfangen. Ein Portlet, das nicht das Ziel einer Benutzeraktion ist, kann optional Container-Ereignisse empfangen, z.B. ein Portlet-Modus-geändert-Ereignis oder Ereignisse von anderen Portlets, z.B. ein Artikel wurde dem Einkaufswagen hinzugefügt-Ereignis.
Die JSR 286 Ereignisverarbeitung wird in der folgenden Abbildung erläutert.
Um Portlets zu erstellen, die die Ereignisfunktion verwenden, gehen Sie folgendermaßen vor
1. Deklarieren Sie die Ereignisse in der portlet.xml
(i) Legen Sie die Ereignisdefinition auf der Ebene der Portlet-Anwendung fest. Damit legen Sie den Ereignisnamen und den Objekttyp fest.
. . . . . . x:Adresse com.xebia.Adresse
@XmlRootElement
public class Address implementiert Serializable {
public Address() {
}
private String Street;
private String city;
private String country;
//Getters und Setters
}
Hinweis: Das Objekt muss serialisierbar sein und mit einer gültigen JAXB-Annotation instrumentiert sein. Dies kann erforderlich sein, um sicherzustellen, dass Portlets Ereignisse an entfernte Portlets senden und von diesen empfangen können. Bei lokaler Kommunikation kann es jedoch vorkommen, dass Portal-Container aus Optimierungsgründen die Ereignis-Nutzdaten nicht serialisieren. KontinentPortlet KontinentPortlet ................. x:Adresse(iii) Geben Sie im Abschnitt Portlet den oben definierten Ereignisnamen für die Portlets an, die dieses Ereignis verarbeiten sollen.
KontinentMapPortlet KontinentMapPortlet x:Adresse KontinentInfoPortlet KontinentInfoPortlet x:Adresse2. Geben Sie im Portlet ein Ereignis aus, das als supported-publishing-event im Portlet angegeben wurde.
public class ContinentPortlet extends GenericPortlet {
public void processAction(ActionRequest Anfrage, ActionResponse Antwort)
throws PortletException,IOException {
QName qname = new QName("https:xebia.com/address" , "Adresse");
Adresse add = new Adresse();
//Werte in Adresse setzen
response.setEvent(qname, add);
}
}
3. Verarbeiten Sie das Ereignis in dem Portlet, das als supported-processing-event im Portlet angegeben wurde.
public class ContinentInfoPortlet extends GenericPortlet {
public void processEvent(EventRequest request, EventResponse response) {
Event event = request.getEvent();
if(event.getName().equals("Adresse")){
Adresse payload = (Adresse )event.getValue();
//verarbeiten Sie hier die Nutzlast
}
}
}
Portlet-Ereignisse bieten im Vergleich zu öffentlichen Render-Parametern eine ausgefeiltere Möglichkeit, Informationen zwischen Portlets auszutauschen, da sie zum Austausch von Objekten und nicht von einfachen Stringwerten verwendet werden können. Sie bieten außerdem eine zusätzliche Callback-Methode, processEvent, mit der die Ereignisinformationen verarbeitet werden können, bevor die Ansicht für das Portlet gerendert wird. Außerdem geben Portlet-Ereignisse die Informationen auf typsichere Weise weiter, da die Ereignis-Payload-ID an einen Typ gebunden ist, den wir in der portlet.xml deklarieren. Außerdem ist in der Portlet-Spezifikation nicht standardisiert, wie die Portlets verdrahtet werden, so dass es den Portal-Containern freisteht, geeignete Mechanismen zu wählen, um die Portlets miteinander zu verdrahten.
Gemäß der Portlet-Spezifikation sind Portlet-Ereignisse jedoch kein so zuverlässiges Kommunikationsmittel wie JMS, da die Spezifikation den Portal-Containern nicht vorschreibt, die Portlet-Ereignisdaten zu speichern. Bei einem Serverausfall können die Portlet-Ereignisse also verloren gehen.
Zusammenfassung
In diesem Blog haben wir über die JSR 286-Funktionen für die Kommunikation zwischen Portlets gesprochen. Zunächst haben wir über die öffentlichen Rendering-Parameter und ihre Funktionsweise gesprochen. Zweitens haben wir über die Portlet-Ereignisse und ihre Funktionsweise gesprochen. Wie entscheiden Sie also, wann Sie sich für eines der beiden oben genannten Portlets entscheiden sollten? Ich würde das folgende Prinzip anwenden
Wenn das Empfängerportlet keine Verarbeitungs-/Bearbeitungslogik ausführen muss, ist es ratsam, öffentliche Render-Parameter zu verwenden, da sie den Overhead für die Erstellung von Portlet-Ereignissen und die Verkabelung der Portlets untereinander vermeiden, die im Falle von Portlet-Ereignissen erforderlich ist. Wie bereits erwähnt, ist die Verkabelung der Portlets untereinander portalcontainerspezifisch und stellt einen zusätzlichen Overhead dar. Damit die Empfänger-Portlets jedoch die gemeinsamen Informationen verarbeiten und typsichere Werte senden können, müssen wir Portlet-Ereignisse verwenden.Insgesamt machen die JSR 286 Portlet-Koordinationsfunktionen komplexe Portalanwendungen modular und verwaltbar. Hinweis: Den Quellcode für Portlet-Ereignisse können Sie hier herunterladen.
Contact