JSF - Java Server Faces Keretrendszer

JSF általában

A keretrendszer

A JSF (Java Server Faces) technológia az egyik leginkább elterjedt webes keretrendszer, annak köszönhetően, hogy épít a JSP (Java Server Pages) technológiára és az MVC (model – view – controller) tervezési mintára.


MVC | Model - view - Controller minta

Egy Java Server Faces alkalmazás, mint általában minden Java alapú webalkalmazás egy servlet konténerben fut, és a következőket tartalmazza: ezeken kívül még A keretrendszer HTML és annál magasabb szintű komponenseket tartalmaz, mint pl.: validátorok, konverterek, amelyek a megjelenítendő adatokat képesek kezelni. A komponensek tartalmazhatnak attribútumokat és akár egymásba ágyazhatóak. A keretrendszer alkalmazása során a programozó az oldalakat jelölő rendszer helyett objektumok segítségével hozza létre. A fejlesztő entitásokkal dolgozik, amelyek tulajdonságokkal bírnak amiket vagy az oldal definicióiban vagy a programban beállíthatók. A keretrendszer az oldalakat futásidőben transzformálja egy komponens fába, ami akár dinamikusan is módosítható komponensek hozzáadásával, eltávolításával.

JSF állapotgép

A JSF minden kérés feldolgozásra egy állapotgépet használ, amely vezérli a folyamatot. A folyamatok 6 állapot egyikébe kerülhet.
  1. A nézet visszaállítása (Restore Wiew - postback)
    • A rendszer a kérés feldolgozása közben megvizsgálja, hogy olyan oldara tér vissza amit már előzőleg elmentett. Ha igen (postback) akkor a JSF ebben a fázisban visszaállítja az egyes komponensek állapotát. Ha nem postback akkor a keretrendszer létrehozza a komponensfa következő elemét és az állapotgép státuszát a nézet generálása állapotba kényszeríti.
  2. A kérés paramétereinek rögzítése (Apply Request Values)
    • Ebben a fázisban ellenőrzésre kerülnek az input komponensek, hogy van-e hozzájuk rendelve paraméter a kérésben. Ha van azt UIinput ősosztály submittedValue tagváltozójában tárolja el.
  3. Validációk futtatása (Process Validation)
    • A ViewRoot-tól kezdve mélységi bejárással történik a komponensek validálása a komponensfában. Ebben a fázisban azok a komponensek kerülnek validálásra amelyekre teljesülnek az alábbi feltételek:
      • a felhasználó által küldött űrlapban szerepelnek
      • rendered attributuma true
      • immediate attributuma false
    Validálási folyamat során első sorban a kapott paraméterek (ha vannak) kerülnek konvertálásra a megfelelő java típusra. A konvertálást vagy a beépített JSF konverter vagy egyedi konverter alapján történik. Ha a validáció hibára fut, akkor a JSF a komponens üzenetei között elhelyez egy üzenetet és az állapotgépet a nézet generálása állapotba. Ha a validálás sikeres, akkor a konvertált és validált értéket beírja a komponens value tagváltozójába.
  4. Modell aktualizálása (Update model values)
    • Ebben a fázisban a validált értékek beírásra kerülnek a modellbe.
  5. Alkalmazás meghívása (Invoke application)
    • Ebben a fázisban a komponenseken keresztül az események továbbításra kerülnek az összes regisztrált osztály felé.
  6. Nézet generálása (Render response)
    • Az aktualizált komponensfát bejárva megtörténik a szükséges kimenet generálása.


JSF állapotgép

JSF alkalmazás könyvtár struktúrája és konfigurálása



Eclipse IDE által generált könyvtár strukúra

Az ECLIPSE IDE fejlesztő környezet a fenti képen látható módon állította elő a JSF alkalmazás könyvtár szerkezetét. Ezek közül amit feltétlen ismernünk kell: A keretrendszert úgynevezett telepítés leíró fájlokon keretül tudjuk konfigurálni. Két fájllal szinte minden esetben találkozunk.
web.xml

A web.xml egy kapcsolatot definiál URL címek és a szervletek között, melyek a kéréseket szolgálják ki. A Webkiszolgáló arra használja ezt a konfigurációs fájlt, hogy megkeresse az adott URL-hez tartozó szervletet, és meghívja a kéréshez tartozó osztály megfelelő metódusát. (pl. a doGet () metódus a HTTP GET kéréseket).

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web=" http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>JSFTest</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <context-param> <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>resources.application</param-value> </context-param> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> </web-app>


faces-config.xml

Az alkalmazás Backing Bean-jeit és az oldalak közötti navigációs logikát egy XML konfigurációs file, a WEB-INF/faces-config.xml írja le. Ez a file további bejegyzéseket is tartalmazhat, amelyek pl. segítik a saját validátorok és konverterek v. a többnyelvű felületek kialakítását (message bundle-ek), stb. is.

<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1"> <managed-bean> <managed-bean-name>hangman</managed-bean-name> <managed-bean-class>jsftest.Hangman</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>cleverTableBean</managed-bean-name> <managed-bean-class>datatable.CleverTableBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/hangman.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/success.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/failure.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/*</from-view-id> <navigation-case> <from-outcome>index</from-outcome> <to-view-id>/index.xhtml</to-view-id> <redirect/> </navigation-case> <navigation-case> <from-outcome>hangman</from-outcome> <to-view-id>/hangman.xhtml</to-view-id> <redirect/> </navigation-case> <navigation-case> <from-outcome>clevertable</from-outcome> <to-view-id>/clevertable.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule> <application> <message-bundle>resources.application</message-bundle> <locale-config> <default-locale>en</default-locale> </locale-config> </application> </faces-config>

xhtml oldalak

A megjelenítésre általában szabványos xhtm oldalakat használ a keretrendszer. Az alábbi forrása a példák között található hangman játék xhtm forráskódját láthatjuk.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Hangman Game</title> </head> <body style="background: url(imgs/backg.jpg); background-size:100% auto;"> <f:view> <h:link value="index" outcome="index" style="width: 200px; height 40px; background: #FFF;" /> <br/><br/> <h1><h:outputText value="Hangman Game 1.0" /></h1> <table style="background: #FFF;"> <tr> <td> <!-- ################################################################### --> <!-- ##### Kiírja a böngésző felületére a value attribútum értékét ##### --> <h:outputText style="color:red" value="The word I'm thinking about is: " /> <!-- ############################################################################## --> <!-- ### Kiírja a böngésző felületére a hangman backing bean word tulajdonságát ### --> <h:outputText value="#{hangman.word}" /><br /><br /> <h:form> <h:outputText value="Show a new letter:" /> <!-- ####################################################################### --> <!-- ### Legördülő menü, kiválasztott érték hangman backing bean ### selectedChar tulajdonsága. Az elemei pedig a hangman backing bean ### availableChars lista ### --> <h:selectOneMenu value="#{hangman.selectedChar}"> <f:selectItems value="#{hangman.availableChars}"/> </h:selectOneMenu> <!-- ################################################################### --> <!-- ### Gomb a hangman backing bean showCharacter metódus hívásához --> <h:commandButton action="#{hangman.showCharacter}" value="Show!"/><br/><br/> <h:outputText value="Type your guess here:" /> <!-- ################################################################### --> <!-- ### Input mező, melynek értéke hozzá van kapcsolva a hangman backing ### bean guess string típusú tulajdonságához --> <h:inputText value="#{hangman.guess}" /> <h:commandButton action="#{hangman.tryGuess}" value="Guess!"/><br/><br/> <br/> <!-- ###################################################################### --> <!-- ### Gomb a hangman backing bean newGame metódus hívásához amellyel ### új játékot kezdeményezhetünk --> <h:commandButton action="#{hangman.newGame}" value="New Game"/><br/><br/> </h:form> </td> <td style="width:30px;"> </td> <td> <!-- ###################################################################### --> <!-- ### Kép megjelenítése a böngészőben. A megjelenítést szabályozva van a ### rendered attribútummal. Az egyes képek csak akkor lesznek láthatóak ### ha a képhez tartozó rendered attribútumban megadott hangman backing ### bean-beli boolean tulajdonság értéke true --> <h:graphicImage value="imgs/hangman.jpg" rendered="#{hangman.startPos}"/> <h:graphicImage value="imgs/hangmanHead.jpg" rendered="#{hangman.head}"/> <h:graphicImage value="imgs/hangmanBody.jpg" rendered="#{hangman.body}"/> <h:graphicImage value="imgs/hangmanLeftHand.jpg" rendered="#{hangman.leftHand}"/> <h:graphicImage value="imgs/hangmanRightHand.jpg" rendered="#{hangman.rightHand}"/> <h:graphicImage value="imgs/hangmanLeftFoot.jpg" rendered="#{hangman.leftFoot}"/> <h:graphicImage value="imgs/hangmanEnd.jpg" rendered="#{hangman.hangmanEnd}"/> </td> </tr> <tr> <td> <div style="background: #FFF;"> <h:outputText value="Selected characters:" /> <br/> <ui:repeat value="#{hangman.notAvailableChars}" var="o"> #{o} <h:outputText value=" | " /> </ui:repeat> </div> </td> </tr> </table> </f:view> </body> </html>

Managed bean (Request bean-ek)

A managed bean (szokás request bean-nek is nevezni) egy JAVA osztály amely a JAVA alapú webes keretrendszer MVC (Model-View-Controller) mintában a controller szerepét tölti be. A managed bean hatókörét és refrenci nevét annotációkkal vagy a faces-config.xml -ben kell definiálni.

Managed bean hatókör

Attól függően mikor kerül szemétgyüjtésre a managed bean megkülönböztetünk

package hu.testJsf.javaee.ejb; import javax.ejb.Stateless; @SessionScoped // adatai elérhetőek amíg a session létezik @Named("TestStateLessBean") // TestStateLessBean néven elérhetjük el az osztályt // - xhtml lapról pl.: #{TestStateLessBean.str} = str értékével public class TestStateLessBean { private String str = "Hello World"; public TestStateLessBean() {} public String getStr() { return str; } public String setStr(String strParam) { return this.str = strParam; } }