# JSF Best practices - Managed beans



## shadow (11. Okt 2010)

Hi,

ich bin Newbie im Thema JSF und habe ein paar Anfängerfragen zum Thema Managed Beans (Backing Beans). Ich programmiere gerade als Beispielanwendung einen Mini-Shop, der folgende Funktionen haben soll:

- Auf verschiedenen Produkt-Seiten sollen Produkte in den Warenkorb gelegt werden können
- Auf der Warenkorb-Übersichts-Seite soll man Produkte wieder entfernen und Stückzahl verwalten können
- Mini-Kundenverwaltung
- Bestellung abschließen, als bereits bestehender Kunde oder Neukunde


Als erstes interessiert mich, wie ich bzgl. der Managed-Beans vorgehe. Also welche konkreten Managed Beans sind hier sinnvoll? Ich bin gerade bei einer ShoppingCartBackingBean, die eine Liste der aktuell im Warenkorb befindlichen Produkte hat. Diese brauche ich auf der Warenkorb-Übersichts-Seite, um eine Tabelle darzustellen. Aber diese Bean wird auch von allen Produktseiten benutzt, um Produkte in die Liste mit aufzunehmen, also ungefähr so:


```
<h:commandLink action="#{ShoppingCartBackingBean.putProductInShoppingCart}" >Mein Produkt</h:commandLink>
```

Ist das sauber? Ist eine andere Herangehensweise sinnvoll? Ich dachte des Öfteren gelesen zu haben, dass eine Backing Bean pro Seite sinnvoll ist...

Mein zweites konkretes Problem ist die Seitennavigation. Auf der Warenkorb-Übersichts-Seite, soll ganz unten ein Button sein, der zum Abschluss der Bestellung führt, besser gesagt auf einer Zwischenseite, auf der man ganz ähnlich wie bei Amazon angeben kann, ob man schon ein Kundenkonto hat, und sich dann einloggt, oder ob man Neukunde ist. Soweit kein Problem. Diese Abfrage soll allerdings komplett entfallen, also übersprungen werden, wenn der Kunde bereits eingeloggt ist, weil ja dann klar ist, dass er schon ein Kundenkonto hat. Und dieses befindet sich auch schon in der Session.

Diese Logik habe ich jetzt auch versucht in der ShoppingCartBackingBean unterzubringen, weil ich nicht weiß, wo sonst. Soll dann in etwa so aussehen:


```
<h:commandButton action="#{ShoppingCartBackingBean.completeOrderProcess}" > ...



@ManagedBean
@SessionScoped
public class ShoppingCartBackingBean {
...
  public String completeOrderProcess() {
    // hier soll sich die Kunden Backing Bean besorgt werden, über EL
    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    CustomerBackingBean customerBackingBean = (CustomerBackingBean) FacesContext.getCurrentInstance().getApplication()
        .getELResolver().getValue(elContext, null, "customerBackingBean");
    ....
    // hier irgendwie entscheiden, ob schon ein Kunde angemeldet ist, und je nachdem ein anderes Ergebnis zurückliefern
    if (customerBackingBean.isLoggedIn()) {
      return "complete_order_process";
    } else {
      return "ask_for_customer_login";
    }

  }
...
}
```

Ich finde es hier allerdings etwas holprig, über getELResolver() auf eine andere Backing Bean zuzugreifen, die Idee habe ich von hier: AccessingOneManagedBeanFromAnother - Myfaces Wiki. Allerdings fällt mir spontan kein anderer Weg ein, dieses Login-Verfahren zu realisieren.

Gibt es hier irgendwelche best practices? Also Zugriff von einer Backing Bean auf eine andere. Macht man das überhaupt so?

Vielen Dank!
Stefan


----------



## JanHH (16. Okt 2010)

Ich würde dringend empfehlen, nicht so starr am Konzept der "Backing Bean" festzuhalten (und schon gar nicht "eine Bean pro Seite"), sondern eher so vorzugehen:

- das Datenmodell der Anwendung (was sowohl Produkte als auch Warenkorb als auch Kunden beinhaltet) wird sauber modelliert anhand von Model Beans bzw. in JEE-Sprache Entity Beans, und zwar OHNE direkten Bezug zu irgendwelchen JSF-Sachen, sondern halt für sich gesehen sauber als Modell

- die Kommunikation zwischen JSF-Seite und dem Model findet über Session Beans bzw. Action Beans statt (die also beispielsweise Listen laden, die in der Seite angezeigt werden, oder auf command-Buttons reagieren). Dabei würde ich aber nicht nach dem Motto "eine Bean pro Seite" vorgehen, sondern nach Funktionalität. Beispielsweise eine Bean die sich um die Verwaltung der Kunden kümmert, eine um die Waren und den Warenkorb, usw. Dabei können durchaus mehrere JSF-Seiten auf die gleiche Action Bean zugreifen.

Wenn man das so macht, lösen sich die meisten Probleme von selber. Zugriff von einer Session Bean auf eine andere passiert entweder (mit seam) per dependency injection (mit @In), oder, bei JSF "pur", indem man die eine als managedProperty der anderen deklariert. Das was in Deinem Code steht geht natürlich auch aber ist natürlich nicht gerade der eleganteste Weg.


----------



## shadow (20. Okt 2010)

Das klingt einleuchtend, ich werde das mal so probieren...

Vielen Dank für die Info!


----------



## MrWhite (20. Okt 2010)

Ich sage dir jetzt die beste best practice bzgl. JSF:

Don't use it.

Nimm Apache Wicket, Tapestry, oder gleich PHP oder irgendwas anderes fuer dein Web-Frontend, aber lass die Finger von JSF. Besonders, wenn du planst auch Javascript Libraries einzusetzen.


----------



## y0dA (25. Okt 2010)

MrWhite hat gesagt.:


> Ich sage dir jetzt die beste best practice bzgl. JSF:
> 
> Don't use it.
> 
> Nimm Apache Wicket, Tapestry, oder gleich PHP oder irgendwas anderes fuer dein Web-Frontend, aber lass die Finger von JSF. Besonders, wenn du planst auch Javascript Libraries einzusetzen.



Und warum?


----------



## Deadalus (25. Okt 2010)

MrWhite hat gesagt.:


> Ich sage dir jetzt die beste best practice bzgl. JSF:
> 
> Don't use it.
> 
> Nimm Apache Wicket, Tapestry, oder gleich PHP oder irgendwas anderes fuer dein Web-Frontend, aber lass die Finger von JSF. Besonders, wenn du planst auch Javascript Libraries einzusetzen.



Sorry ich sehe das komplett anders. JSF ist eine sehr einfache und gute Spezifikation für ein WebFramework. Ok mit JSF 1.2 gab es noch mehrere Probleme und der ganze XML Kram hat wirklich genervt. Mit JSF 2.0 aber sind diese Probleme gelöst. 

Da JSF ein internationaler Standard ist gibt es auch viel Hilfe und zusätzliche Bibliotheken. Am bemerkenswertesten ist wohl das PrimeFaces Projekt: PrimeFaces - ShowCase. 

Mit Hilfe einer solchen Bibliothek kannst du dir 90% des JS Krams sparen. Der Rest harmonisiert wunderbar mit jQuery. Ein groß teil der PF Komponenten bauen sogar auf jQuery auf.


----------



## Kai Wähner (31. Okt 2010)

> Sorry ich sehe das komplett anders. JSF ist eine sehr einfache und gute Spezifikation für ein WebFramework. Ok mit JSF 1.2 gab es noch mehrere Probleme und der ganze XML Kram hat wirklich genervt. Mit JSF 2.0 aber sind diese Probleme gelöst.



Sehe ich genau so. Neben den Komponenten-Bibliotheken gibt es auch noch viele andere "Addons", beispielsweise JBoss Seam oder CaptainCasa. 
Außerdem gibt es - und das ist für mich der Vorteil des Standards - deutlich mehr Ressourcen wie Bücher, Tutorials, usw.



> Da JSF ein internationaler Standard ist gibt es auch viel Hilfe und zusätzliche Bibliotheken. Am bemerkenswertesten ist wohl das PrimeFaces Projekt: PrimeFaces - ShowCase.



Da sollte man man aus meiner Sicht einfach Projekt-spezifisch bewerten, welche Bibliotheken die "bemerkenswertesten" und hilfreichsten sind ?! Es gibt ja auch noch andere weit verbreitete Alternativen wie ICEFaces oder RichFaces.


----------



## GIBMIRKRAFT (1. Nov 2010)

Zu deiner Frage:

Am Besten macht es sich, eine Controller-Architektur im Vorfeld zu überlegen. Ich gebe meinen Vorgänger recht -> die Schnittstelle zur Geschäftslogik sollte möglichst klein gehalten werden.


Bsp.

```
<Name>Controller -> alle Aktion (Speichern, Abbrechen, etc.)
<Name>OptionDaten-> alle Auswahllisten
<Name>EventHandler-> alle auftretenden Ereignisse abfangen.
```
In den letzten Projekten hat sich diese Art der Vorgehensweise sehr gut bewährt... Am meisten Sinn macht es den ViewScope zu verwenden, d.h. die Klasse ist so lange gültig bis die Seite gewechselt wird. SessionScope nimmt man nur für Daten die zu einen Benutzer gehören.


@MrWhite

PHP (das kann doch keiner ernst nehmen!)? Tapestry? Am Besten man verwendet gleich wieder nur Servlets und JSP oder was???

1. JSF ist das einigste, standardisierte UI-Framework im Java EE Bereich -> jcp.org  

2. Dadurch, das die Technologie einem Standard unterliegt, ist die Technologie beständiger, wird ständig weiterentwickelt und von den meisten Plattformen unterstützt -> in Gegensatz zu irgendwelchen Open Source Produkten.

3. "Irgendwelche JavaScript..." Ich hasse Leute die keine Ahnung haben... Ich habe gerade ein Projekt am Laufen wo genau so ein Clown unterwegs war und den Leuten erzählt wie scheiße JSF sei. Der Sack hat eine Technologie genommen die seit über 2 Jahren nicht mehr weiter entwickelt wird. Die Firma hat den Mist jetzt an der Backe und darf teueres Geld bezahlen für Freelancer die das Projekt auf JSF umbauen!

JSF integriert alles was man braucht, auch bereits von der Version 1.2 ->
Annotations -> Apache Shale
Ajax -> Richfaces, IceFaces,Primefaces, Openfaces, etc....
EJB3-> Seam
Templating, Composite Components -> Facelets
usw. usw. usw.


----------



## Kai Wähner (1. Nov 2010)

> JSF integriert alles was man braucht, auch bereits von der Version 1.2



Jein 

Wenn du damit die Realisierung klassischer Webanwendungen ansprichst, wo auch Tapestry, Wicket, Struts etc. dazu gehören, dann stimme ich dir voll zu!

Aber eine "richtige" Rich Internet Application mit Animationen etc., wie man sie mit JavaFX oder Flex erstellt, ist mit JSF nur schwer möglich. Ein gutes Beispiel hierfür ist Pokerstars - das wird ganz schwer mit JSF


----------



## GIBMIRKRAFT (1. Nov 2010)

Naja gut aber durch das Komponenten-Modell von JSF kannst du mühelos eine Technologie integrieren:

JSF-Flex:
Using JSF and Flex Components Together | Javalobby

Weitere Bsp.

1. Wir haben für ein Unternehmen in JSF-Komponenten -> JS Charts – Free JavaScript charts integriert, war ne coole Sache...

2. Oder wir haben für eine Logistik Firma JSF Komponente für deren Scanner erstellt.

In Gegensatz zu Struts o. Stripes -> was für mich eher eine Controller- statt eine Web-Technologie darstellt, habe ich bei JSF  wiederverwendbare Komponenten und kann durch composite-components ganze Seiteninhalt als Template hinterlegen.

Ist halt Geschmaksache und es kommt immer auf den Anwendungsfall drauf an. Für Firmenwebseiten habe ich auch damals kleine, schmutzige  Anwendung auf PHP Basis erstellt...


----------

