Schöneres JSF mit PrettyFaces

  • JavaServer Faces war in der Vergangenheit oft Kritik ausgesetzt. Eines der Hauptargumente der Kritiker sind die häufigen POST-Requests für selbst einfachste Navigation innerhalb der Applikation. Darunter leidet vor allem die Benutzerfreundlichkeit, da beispielsweise das Setzen von Lesezeichen unmöglich wird. Besser wäre sicherlich die Verwendung von menschenlesbaren URLs in Verbindung mit einfachen HTML-Links. Mit PrettyFaces lässt sich dies in JSF-Applikation umsetzen.

    JavaServer Faces gehört heute zu den am weitesten verbreiteten Frameworks für die Entwicklung moderner Webanwendungen. Trotz seiner Popularität und der großen Anzahl von Komponentenbibliotheken stoßen Entwickler jedoch immer wieder auf dieselben Probleme. Einige dieser Schwierigkeiten rühren daher, dass die meisten Anfragen einer JSF-Applikation an den Server POST-Requests sind. Für Seiten, die das Ergebnis eines POST-Requests sind, lassen sich beispielsweise keine Lesezeichen setzten, da der Browser beim Aufruf des Lesezeichens lediglich einen GET-Request sendet. Ein weiteres Problem sind die so genannten Form-Resubmission-Dialoge. Betätigt der Benutzer den ZURÜCK-Button des Browsers, wird er von einem Dialog vor den potenziellen Konsequenzen gewarnt (Abb. 1). Und diese Warnung ist nicht unbegründet: Viele Applikationen führen die durch den vorherigen Request angestoßene Aktion einfach noch einmal aus. Im schlechtesten Fall hat man die Bestellung im Onlineshop damit ein zweites Mal aufgegeben.


    Abb. 1: Der Form-Resubmission-Dialog von Firefox


    Besonders bei der reinen Navigation innerhalb der Applikation stören die Postbacks enorm. Eine Alternative wäre die konsequente Verwendung von einfachen HTML-Links in Verbindung mit RESTful URLs. Leider unterstützt JSF dieses Vorgehen nur sehr eingeschränkt. Zwar hat sich die Lage durch die Einführung von in JSF 2.0 verbessert, jedoch vermisst man hier immer noch mehr Flexibilität. Genau an dieser Stelle setzt PrettyFaces an. Es erlaubt die Erstellung von einfachen menschenlesbaren URLs und integriert sich nahtlos in das Navigationskonzept von JSF. Zusätzlich bietet PrettyFaces eine Reihe von häufig benötigten Features, wie beispielsweise Page Actions und eine eigene Rewrite Engine.
    Um im Folgenden praxisnahe Anwendungsfälle beschreiben zu können, wird die Verwendung von PrettyFaces am Beispiel eines Onlineshops vorgestellt. Das Datenmodell ist absichtlich sehr einfach gehalten. Der Shop bietet Bücher an, die eindeutig durch ihre ISBN-Nummer identifiziert werden und einer oder mehreren Kategorien zugeordnet sind. Unsere Applikation verwendet JSF 2.0 in Verbindung mit CDI. Es sei jedoch angemerkt, dass PrettyFaces genauso gut in anderen Umgebungen funktioniert, beispielsweise mit JSF 1.x und Spring.
    Installation
    Zur Einbindung ins Projekt werden neben dem PrettyFaces-Archiv noch Apache-Commons-Bibliotheken benötigt. Verwendet man Apache Maven, muss lediglich das entsprechende Maven-Artefakt in die pom.xml eingetragen werden. Alle benötigten Abhängigkeiten werden dann automatisch dem Projekt hinzugefügt. Bei der Verwendung von JSF 2.0 in einem Servlet-3.0-Container ist die Konfiguration durch das Hinzufügen des PrettyFaces-Archivs bereits vollständig abgeschlossen. Der benötigte Servlet-Filter wird in diesem Fall automatisch vom Container eingebunden. In allen anderen Fällen muss er manuell in die web.xml eingetragen werden (Listing 1).








    Pretty Filter
    com.ocpsoft.pretty.PrettyFilter


    Pretty Filter
    /*
    REQUEST
    FORWARD
    ERROR




    Listing 1: web.xml

    Mapping
    Als Einstieg in den Shop dient die Startseite mit einer Liste aller Buchkategorien. Das für diese Seite zuständige Bean ist in Listing 2 zu sehen. Die CDI-Annotationen @Named und @RequestScoped legen den Namen und den Scope für das Bean fest. Mit der PrettyFaces-Annotation @URLMapping wird ein URL-Mapping erzeugt. Das pattern-Attribut gibt dabei den gewünschten URL an, und viewId verweist auf die darzustellende JSF-View. Das Mapping verbirgt die eigentliche JSF-Seite hinter einem nahezu beliebigen URL, der nicht dem durch das FacesServlet vorgegebenen Format entsprechen muss (/faces/* bzw. *.jsf). Darüber hinaus wird für jedes URL-Mapping eine eindeutige ID benötigt.




    @Named("homeBean")
    @RequestScoped
    @URLMapping(id="home", pattern="/home", viewId="/faces/home.xhtml")
    public class HomeBean {

    @Inject
    private CategoryDao categoryDao;

    private List categories;

    @URLAction
    public void initView() {
    categories = categoryDao.getCategories();
    }

    /* Getter + Setter */
    }


    Listing 2: HomeBean.java

    Page Actions
    Bevor die Seite gerendert werden kann, benötigen wir die darzustellenden Kategorien. Diese Liste wird in der Methode initView() aus der Datenbank geladen und in der Bean gespeichert. Die Annotation @URLAction weist PrettyFaces an, die Methode bei jedem Zugriff auf das URL-Mapping aufzurufen. Der Aufruf einer Page Action findet standardmäßig in der RestoreView-Phase statt. Mithilfe des phaseId-Attributs kann jedoch auch jede andere Phase des JSF Lifecycle verwendet werden. Anzumerken ist an dieser Stelle, dass die Methode bei jedem Request an den konfigurierten URL aufgerufen wird. Das schließt vor allem auch JSF Postbacks mit ein. Sollte das nicht gewünscht sein, so lässt sich das Standardverhalten durch Setzen des onPostback-Attributs auf false abschalten. Das kann vor allem dann Sinn machen, wenn die Bean den View Scope verwendet und sein Status somit bis zum Postback erhalten bleibt. Mit dieser Bean ist nun alles für die View vorbereitet. Listing 3 zeigt die zugehörige XHTML-Seite, die alle Kategorien in Tabellenform anzeigt.












    Name




    Beschreibung











    Listing 3: home.xhtml

    Path-Parameter
    Im nächsten Schritt werden wir eine Seite erstellen, die alle Bücher einer bestimmten Kategorie anzeigt. Im Gegensatz zur Startseite ist diese Seite von einem Parameter abhängig. Damit die Seite eigenständig funktionieren kann, muss die Kategorie Bestandteil des URL sein. Optimal wäre sicherlich ein URL wie /category/Java. Glücklicherweise lässt sich eine solche Anforderung mit PrettyFaces leicht erfüllen.





    Ihre Meinung zum Artikel? Wir freuen uns über Kommentare und Empfehlungen.


    Teil 1 Teil 2 Teil 3

    293 mal gelesen