jsf-forum.de jsf-forum.de jsf-forum.de
jsf-forum.de    
jsf-forum.de

Architektur - oder: wie gehe ich richtig mit JSF um?

Architektur ist sicherlich ein wenig hoch gegriffen, aber häufig reicht es eben nicht aus, die Technologie zu kennen. Es ist genauso notwendig, eine neue Technologie auch richtig einzusetzen.

Teils aus Diskussionen aus JSF-Foren, teilweise aus Rückmeldungen von Entwicklern und teilweise aus der persönlichen Erfahrung des Verfassers werden im folgenden Architekturvorschläge und Architekturentscheidungen vorgestellt und deren Vorteile aber auch Nachteile besprochen.

Aber Vorsicht! DIE 100%ig richtige und für alle Anwendungsfälle passende Architektur gibt es nicht. Daher sind die folgenden Vorschläge auch als Empfehlungen zu verstehen, nicht als einzigseligmachende Kopiervorlage :-)

Fragestellungen

   Action oder ActionListener?
   Wo realisiere ich einen EJB-Aufruf
   JSF-Aufruf mit Query-Parameter



Action oder ActionListener?
JavaServer Faces (JSF) bietet zunächst einmal zwei Möglichkeiten, um auf Ereignisse zu reagieren: Über ActionListener (bzw. auch ValueChangeListener) kann ein Listener an eine Komponente (z.B. einen Button) angehängt werden. Wird der Button gedrückt, wird ein Event ausgelöst.

Die zweite Möglichkeit ist, direkt an eine Command-Komponente (also einen Commandbutton oder einen Hyperlink) eine Action anzuhängen. Diese wird ebenfalls beim Auslösen eines Commands ausgeführt.

In Schulungen werde ich oft gefragt, wann ein ActionListener verwendet werden soll und wann eine Aktionsmethode. Die Antwort fällt mir immer etwas schwierig. Prinzipiell kann ich mittels beider Wege technisch alles umsetzen. Allerdings es es in einer Aktionsmethode einfacher, die Navigation zu beeinflussen, in dem ein entsprechender Rückgabewert zurückgeliefert wird. Zwar kann man in einem ActionListner ebenfalls die Navigation beeinflussen, dies ist jedoch nur über Umwege möglich.
Von der Architektur her betrachtet sollte jedoch der ActionListener dazu verwendet werden, um z.B. Änderungen an der Gui durchzuführen. Soll eine "richtige" Aktion durchgeführt werden, also z.B. ein Datenbankzugriff, sollte der Aufruf in einer Action-Klasse erfolgen.
Folgendes Beispiel: Oftmals hat man abhängige Comboboxen. In einer ersten Box wähle ich z.B. das Land aus, in einer zweiten Box das Bundesland (bzw. in der Schweiz die Kantone). Damit nach Auswählen der ersten Box die zweite Box mit entsprechenden Werten befüllt wird, eignet sich hier ein ActionListener. Wenn der Benutzer die gemachte Auswahl z.B. mittels "Speichern" dann bestätigen würde, wäre eine Aktionsmethode der geeignete Ansatzpunkt.

Wo realisiere ich einen EJB-Aufruf?
Diese Frage könnte direkt aus der obigen Frage abgeleitet werden. Ein EJB-Aufruf wird am besten in der Aktionsmethode eingebaut.

JSF-Aufruf mit Query-Parameter?
Folgendes Problem: Sie wollen von einer ganz anderen Seite oder Anwendung auf eine JSF-Seite verlinken. Auf dieser möchten Sie beispielsweise die Telefonnummer einer Person anzeigen. Diese Seite sollte z.B. folgendermassen aufgerufen werden:

www.firma.de/detailanzeige.jsp?person=mustermann

In der JSF-Anwendung muss jetzt also ein Managed-Bean bereitstehen, das genau die Informationen des Herrn Mustermann beinhaltet. Jetzt stellt sich die Frage, wie dem Managed-Bean die Id für den Datenbankzugriff übergeben werden kann.

Leider existiert hier in JSF kein richtiger Lösungsweg. Es ist nach wie vor eine offene Frage, und in vielen Foren wird darüber philosophiert. Es gibt einige Ansätze, dieses Problem zu lösen, dies sind meiner Meinung nach nur Workarounds, eine definitive Lösung fehlt noch.

Die Workarounds, mit denen das gewünschte Verhalten erreicht werden kann sind:
1) Einbau eines Skriptlets: Mit einem Skriplet kann der Query-Parameter auswertet werden und damit das Managed-Bean initialisiert werden:
<% BeanCreator.createBean("com.bean.PersonBean", request.getParameter("person")); %>
Es wird also eine Hilfsfunktion aufgerufen, die als Paramter den Requestparameter übergeben bekommt. In der Hilfsfunktion wird das Managed-Bean bereitgestellt und kann im weiteren Verlauf der Seite wie üblich angesprochen werden.

2) Initalisieren des Managed-Beans mit dem Query-String

<managed-bean>
 <managed-bean-name>PersonBean</managed-bean-name>
 <managed-bean-class>com.bean.PersonBean</managed-bean-class>
 <managed-bean-scope>request</managed-bean-scope>
 <managed-property>
  <property-name>person</property-name>
  <value-ref>requestScope.id</value-ref>
 </managed-property>
</managed-bean>

Dieser Ansatz hat allerdings den großen Nachteil, dass das Objekt im Request-Scope liegt und nicht im Session-Scope ...

3) Verwendung eines Controller-Servlets
Die sicherlich aufwendigste, aber vom Design her sauberste Lösung ist die Verwendung eines FrontController-Servlets. Die JSP-Seite wird nicht mehr direkt aufgerufen, sondern über ein Servlet, das den Query-String auswertet, Managed-Beans bereitstellt und daraufhin auf die eigentliche JSP-/JSF-Seite weiterleitet. Ein Beispiel dazu ist unter dem Kapitel "Tutorials" zu finden.

jsf-forum.de