Foren

Portlet Event im BackingBean

pseudo - -, geändert vor 14 Jahren.

Portlet Event im BackingBean

New Member Beiträge: 16 Beitrittsdatum: 26.05.09 Neueste Beiträge
Hallo!

Ich möchte ein Portletevent von einem BackingBean aus abfeuern und in einem anderen BackingBean wieder empfangen.
Das senden des Events funktioniert soweit ganz gut. Hier der Code:

String name="testEvent";
FacesContext facesContext = FacesContext.getCurrentInstance();
Object responseObject = facesContext.getExternalContext().getResponse();
if (responseObject != null && responseObject instanceof ActionResponse) {
	ActionResponse actionResponse = (ActionResponse) responseObject;
	actionResponse.setEvent(new QName("http://www.mycompany.com/portlet", "NameEvent"),name);
} 


Für das empfangen hatte ich mir folgendes überlegt:

String eventName;
FacesContext facesContext = FacesContext.getCurrentInstance();
Object requestObject = facesContext.getExternalContext().getRequest();
			
if (requestObject != null && requestObject instanceof EventRequest) {
        EventRequest eventRequest = (EventRequest) requestObject;
	QName qName = eventRequest.getEvent().getQName();		
	if (qName.equals(new QName("http://www.mycompany.com/portlet", "NameEvent"))) {
		eventName = (String) eventRequest.getEvent().getValue();
	}
} 


Dies funktioniert allerdings nicht, da requestObject nie ein EventRequest ist.
Kann mir jemand sagen wie ich sonst ein Event im BackingBean empfange?

Vielen Dank schon mal!!!
thumbnail
Steffen Schuler, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

Regular Member Beiträge: 137 Beitrittsdatum: 12.05.08 Neueste Beiträge
eine BackingBean... hört sich irgendwie nach JSF an... und wenn da JSF im Spiel ist, wäre es hilfreich zu wissen, ob du evtl. mit IceFaces herumspielst... vieleicht kannst du zu deiner JSF Implementierung noch ein paar Details loswerden. evtl. gibt es da auch spezielle Möglichkeiten dir zu helfen.

Um was für eine backingBean handelt es sich denn? Wahrscheinlich um eine die im SessionScope liegt!? Kannsz due evtl. dein abstraktes Beispiel konkretiseiren?

Ist das so gemeint?

BackingBean feuert ein Event -> JSF Component wird benachrichtigt und zeigt etwas an -> ruft wiederum eine BackingBean auf
pseudo - -, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

New Member Beiträge: 16 Beitrittsdatum: 26.05.09 Neueste Beiträge
Also zunächst arbeite ich mit MyFaces (IceFaces nicht bei).
Ich möchte vereinfacht gesagt folgendes machen:
Ich habe ein Portlet A mit JSF und die dazugehörige BackingBean (SessionScope).
Ich möchte in diesem Portlet einen Namen eingeben. Dieser name soll mittels Event an ein anderes Portlet B (auch JSF, BackingBean Session Scope) gesendet werden.
D.h. das Event muss irgendwie in der BackingBean empfangen werden, um es dann anzeigen zu lassen.

Hier nochmal der vereinfachte Quellcode:

PortletA

<div xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core">
	<f:view>
		<h:form>
			<table>
			<tbody><tr>
				<td>
					<h:outputtext value="please_enter_your_name" />
				</td>
				<td>
					<h:inputtext id="name" required="true" value="#{ABackingBean.name}" />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<h:commandbutton action="#{ABackingBean.send}" value="success" />
				</td>
			</tr>
			</tbody></table>
		</h:form>
	</f:view>	
</div>


ABackingBean

public class ABackingBean {
       private String name;
       public void setName(String name) {
		this.name=name;
	}

	/**
	 * Method that is backed to a submit button of a form.
	 */
	public String send() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
               Object responseObject = facesContext.getExternalContext().getResponse();
      
		// Event publishing
		FacesContext facesContext = FacesContext.getCurrentInstance();
		Object responseObject = facesContext.getExternalContext().getResponse();
		if (responseObject != null &amp;&amp; responseObject instanceof ActionResponse) {
			ActionResponse actionResponse = (ActionResponse) responseObject;
			actionResponse.setEvent(new QName("http://www.mycompany/portlet", "NameEvent"),name);
		} 
		return ("success");
	}
}


PortletB

<div xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
        <f:view>
	       <h:outputtextvalue="#{bbackingbean.name}" />
        </f:view>
</div>


Hier das was ich mir für das empfangen des Events überlegt habe, was aber wie gesagt nicht funktioniert.
BBackingBean

public class BBackingBean {
     public String getName() {
		// Event processing
		String name="";
		FacesContext facesContext = FacesContext.getCurrentInstance();
		Object requestObject = facesContext.getExternalContext().getRequest();
		if (requestObject != null &amp;&amp; requestObject instanceof EventRequest) {
			EventRequest eventRequest = (EventRequest) requestObject;
			QName qName = eventRequest.getEvent().getQName();
			 if (qName.equals(new QName( "http://www.mycompany.com/portlet", "NameEvent"))) {
				 name = (String) eventRequest.getEvent().getValue();
			}
		} 
		return name;
	}
}
thumbnail
Steffen Schuler, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

Regular Member Beiträge: 137 Beitrittsdatum: 12.05.08 Neueste Beiträge
mit dem JSR 286 gibt es eine neue Version der InterPortletCommunication. Das könnte helfen. Allerdings scheint es mir als setzt du rein auf JSF + BBeans ... ich glaube mich zu erinnern, dass es mit den Scopes beim Einsatz von Portlets einige Unterschiede gab... aber nicht mehr welche. Ich kann dir bezgl. MyFaces nicht sagen, ob das richtig oder flasch ist, gehen sollte oder nicht, aber eben eine Alternative nennen - die Inter Porlet Communication des JSR 286. Kannst du noch deine portlet.xml posten? (Wahrscheinlich steht dort eine MyFaces speziefische Klasse als Portlet drinnen, und ein Verweis auf die JSF-Seite...)
pseudo - -, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

New Member Beiträge: 16 Beitrittsdatum: 26.05.09 Neueste Beiträge
Hier meine portlet.xml

<!--?xml version="1.0"?-->
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/
            portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/portlet/
            portlet-app_2_0.xsd
            http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0">

	<portlet>
		<portlet-name>1</portlet-name>
		<display-name>My Portlet1</display-name>
		<portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>
		<init-param>
			<name>default-view</name>
			<value>/helloWorld.xhtml</value>
		</init-param>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>view</portlet-mode>
		</supports>
		<portlet-info>
			<title>My Portlet1</title>
			<short-title>My Portlet1</short-title>
			<keywords>My Portlet1</keywords>
		</portlet-info>
		<security-role-ref>
			<role-name>administrator</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>guest</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>power-user</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>user</role-name>
		</security-role-ref>

		<supported-publishing-event>
			<qname xmlns:mycomp="http://www.mycompany.com/portlet">mycomp:NameEvent</qname>
		</supported-publishing-event>
	</portlet>

	<portlet>
		<portlet-name>2</portlet-name>
		<display-name>My Portlet2</display-name>
		<portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>
		<init-param>
			<name>default-view</name>
			<value>/showEvent.xhtml</value>
		</init-param>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>view</portlet-mode>
		</supports>
		<portlet-info>
			<title>My Portlet2</title>
			<short-title>My Portlet2</short-title>
			<keywords>My Portlet2</keywords>
		</portlet-info>
		<security-role-ref>
			<role-name>administrator</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>guest</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>power-user</role-name>
		</security-role-ref>
		<security-role-ref>
			<role-name>user</role-name>
		</security-role-ref>

		<supported-processing-event>
			<qname xmlns:mycomp="http://www.mycompany.com/portlet">mycomp:NameEvent</qname>
		</supported-processing-event>
	</portlet>

	<event-definition>
		<qname xmlns:mycomp="http://www.mycompany.com/portlet">mycomp:NameEvent</qname>
		<value-type>java.lang.String</value-type>
	</event-definition>
</portlet-app>
thumbnail
Steffen Schuler, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

Regular Member Beiträge: 137 Beitrittsdatum: 12.05.08 Neueste Beiträge
Wenn der Parameter in der BackingBeanA gesetzt wurde, kann doch eigentlich die BackingBeanA den gleichen Parameter in der BackingBeanB setzen. Allerdings müsste dann diese Methode zum setzen des gleichen Parameters auch in der BackingBeanB implementiert sein.

public class BackingBeanA{
private String name;

public void setName(name){
this.name = name;
}

// Du holst dir über den Faces-Context eine Referenf auf die BBackingBean die in deiner faces-config.xml definiert ist
public String send(){

FacesContext facesContext = FacesContext.getCurrentInstance();
BBackingBean bbb = (BBackingBean) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "BBackingBean");
bbb.setName(name);

return(success);
}
}

// Allerdings benötigst du auch für die BBackingBean die Möglichkeit, den Namen zu setzen
// Aber dafür sollten einfache setter und getter ausreichen

public class BBackingBean{
private String name;

public void setName(name){
this.name = name;
}

public String getName(){
return name;
}
}


... keine Ahnung ob das genau das ist wonach du suchst. Bislang nutz du die eigentlichen Portlet-Features nicht. da gibt es dann die Möglichkeit über die Inerportlet-Communication Nachrichten zwischen Portlets auszutauschen...
pseudo - -, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

New Member Beiträge: 16 Beitrittsdatum: 26.05.09 Neueste Beiträge
Vorab erstmal danke für deine Mühe!

Das mit dem setzen der Parameter direkt in der BackingBean ist eigentlich nicht das was ich wollte.
Zur Interportlet-Communication:
Das ist ja gerade das was ich versuche zu nutzen. Ich möchte ein Event versenden:
actionResponse.setEvent(new QName("http://www.mycompany.com/portlet", "NameEvent"),name);


und dieses Event dann verarbeiten:

QName qName = eventRequest.getEvent().getQName();       
if (qName.equals(new QName("http://www.mycompany.com/portlet", "NameEvent"))) {
	eventName = (String) eventRequest.getEvent().getValue();
}


Mit den PublicRenderParametern funktioniert das Ganze, allerdings nicht mit Events.
Wie gesagt bei den Events geht die Verarbeitung schief, da eventRequest nie vom Typ EventRequest ist (so sieht es zumindest aus).
Matthias Schmitz, geändert vor 14 Jahren.

RE: Portlet Event im BackingBean

New Member Beiträge: 7 Beitrittsdatum: 31.08.09 Neueste Beiträge
Hallo,

folgendes konnte ich während der Recherche für meine Bachelorarbeit herausfinden.

Eventhandling ist für JSF-Portlets nur einseitig möglich. D.h. JSF-Portlets können Events nur verarbeiten (sprich empfangen). Das senden ist im Portlet-Bridge Standard nach JSR-329 nicht vorgesehen, da man davon ausgeht, dass JSF-Portlets grundsätzlich nur in einem Portlet agieren. Daher ist lediglich vorgesehen, einen Event Handler zu registrieren, der beim Eintreffen von Portlet Events aufgerufen wird.
[vgl Bosch Andy; Portlets und JavaServer Faces, Frankfurt am Main 2009, S- 229]

Natürlich sollte es aber möglich, das Senden von Events eingeständig in Backing_Beans zu programmieren. Selber habe ich es aber noch nicht ausprobiert, da ich mit dem Portlet-Bridge Standard JSR-301 (Portlet 1.0/ JSF 1.2) arbeite und in der Portlet Version 1.0 noch kein Eventhandling vorgesehen ist.

Ich habe hier mal eine Übersicht zusammengestellt, welche Möglichkeiten man bei der "Inter Portlet Communication" hat. Bitte korrigiert mich wenn etwas nicht stimmt:

1. Portlet 1.0/ JSF 1.2: Über den Portlet ApplicationScope (Vorteil: Es können Objekte übertragen werden)
2. Portlet 2.0/ JSF 1.2: Punlic-Render-Parameter (Einschränkung: Nur String oder String-Arrays)
3. Portlet 3.0/ JSF 1.2: Portlet Events (Einschränkung siehe Oben)