Skip to content

10. Version 5 – PAM-Web-/JSF-Anwendung

10.1. Anwendungsarchitektur

Die Architektur der PAM-Webanwendung sieht wie folgt aus:

In dieser Version wird der GlassFish-Server alle Schichten der Anwendung hosten:

  • Die [Web-]Schicht wird vom Servlet-Container des Servers gehostet (1 unten)
  • die anderen Schichten [Geschäftslogik, DAO, JPA] werden vom EJB3-Container des Servers gehostet (2 unten)

Die [Geschäftslogik, DAO]-Komponenten der im EJB3-Container ausgeführten Anwendung wurden bereits in der in Abschnitt 7.1 behandelten Client/Server-Anwendung implementiert, die folgende Architektur aufwies:

Die [Geschäftslogik-, DAO-]Schichten liefen im EJB3-Container des GlassFish-Servers, und die [UI-]Schicht lief in einer Konsolen- oder Swing-Anwendung auf einem anderen Rechner:

In der Architektur der neuen Anwendung:

muss nur die [Web-/JSF-]Schicht programmiert werden. Die anderen Schichten [Business, DAO, JPA] sind bereits vorhanden.

In Dokument [ref3] wird gezeigt, dass eine Webanwendung, bei der die Web-Schicht mit Java Server Faces implementiert ist, eine Architektur aufweist, die in etwa wie folgt aussieht:

Diese Architektur implementiert das MVC-Entwurfsmuster (Model, View, Controller). Die Verarbeitung einer Client-Anfrage verläuft wie folgt:

Wenn die Anfrage mit einem GET-Request gestellt wird, werden die folgenden zwei Schritte ausgeführt:

  1. Anfrage – Der Client-Browser sendet eine Anfrage an den Controller [Faces Servlet]. Der Controller verarbeitet alle Client-Anfragen. Er ist der Einstiegspunkt der Anwendung. Er ist das C in MVC.
  2. Antwort – Der C-Controller weist die ausgewählte JSF-Seite an, sich darzustellen. Dies ist die Ansicht, das V in MVC. Die JSF-Seite verwendet ein M-Modell, um die dynamischen Teile der Antwort zu initialisieren, die sie an den Client senden muss. Dieses Modell ist eine Java-Klasse, die die [Business]-Schicht [4a] aufrufen kann, um der V-Ansicht die benötigten Daten zur Verfügung zu stellen.

Wenn die Anfrage über einen POST erfolgt, finden zwischen der Anfrage und der Antwort zwei zusätzliche Schritte statt:

  1. Anfrage – Der Browser-Client sendet eine Anfrage an den [Faces Servlet]-Controller.
  2. Verarbeitung – der C-Controller verarbeitet diese Anfrage. Tatsächlich geht eine POST-Anfrage mit Daten einher, die verarbeitet werden müssen. Dabei wird der Controller von anwendungsspezifischen Ereignisbehandlungsroutinen [2a] unterstützt. Diese Routinen benötigen möglicherweise die Geschäftsschicht [2b]. Die Ereignisbehandlungsroutine muss unter Umständen bestimmte M-Modelle [2c] aktualisieren. Sobald die Anfrage des Clients verarbeitet wurde, kann dies verschiedene Antworten auslösen. Ein klassisches Beispiel ist:
    • eine Fehlerseite, wenn die Anfrage nicht korrekt verarbeitet werden konnte
    • ansonsten eine Bestätigungsseite

Der Ereignisbehandler gibt ein Ergebnis vom Typ String, einen sogenannten Navigationsschlüssel, an den Controller zurück [Faces Servlet].

  1. Navigation – Der Controller wählt die JSF-Seite (= Ansicht) aus, die an den Client gesendet werden soll. Diese Auswahl basiert auf dem vom Ereignis-Handler zurückgegebenen Navigationsschlüssel.
  2. Antwort – Die ausgewählte JSF-Seite sendet die Antwort an den Client. Sie verwendet ihr M-Modell, um ihre dynamischen Teile zu initialisieren. Dieses Modell kann auch die [Business]-Schicht [4a] aufrufen, um die JSF-Seite mit den benötigten Daten zu versorgen.

In einem JSF-Projekt:

  • ist der Controller C das [javax.faces.webapp.FacesServlet]-Servlet. Dieses befindet sich in der [jsf-api.jar]-Bibliothek.
  • Die V-Ansichten werden durch JSF-Seiten implementiert.
  • Die M-Modelle und Ereignisbehandler werden durch Java-Klassen implementiert, die oft als „Backing Beans“ bezeichnet werden.
  • In JSF-Versionen 1.x werden die Bean-Definitionen und die Regeln für die Navigation von einer Seite zur anderen in der Datei [faces-config.xml] definiert. Sie enthält die Liste der Ansichten und die Regeln für den Übergang von einer zur anderen. Ab JSF-Version 2 können Bean-Definitionen mithilfe von Annotationen erstellt und Seitenübergänge direkt im Bean-Code fest codiert werden.

10.2. So funktioniert die Anwendung

Wenn die Anwendung zum ersten Mal aufgerufen wird, erscheint die folgende Seite:

Anschließend füllen Sie das Formular aus und beantragen das Gehalt:

Es wird folgendes Ergebnis angezeigt:

Diese Version berechnet ein fiktives Gehalt. Achten Sie nicht auf den Inhalt der Seite, sondern auf deren Layout. Wenn Sie auf die Schaltfläche [Zurücksetzen] klicken, gelangen Sie zurück zu Seite [A].

Falsche Eingaben werden markiert, wie im folgenden Beispiel gezeigt:

10.3. Das NetBeans-Projekt

Wir werden eine erste Version der Anwendung erstellen, in der die [Business]-Schicht simuliert wird. Wir werden die folgende Architektur verwenden:

Wenn Ereignisbehandler oder Modelle Daten von der [Business]-Schicht [2b, 4a] anfordern, stellt diese ihnen fiktive Daten zur Verfügung. Das Ziel ist es, eine Webschicht zu erhalten, die korrekt auf Benutzeranfragen reagiert. Sobald dies erreicht ist, muss nur noch die in Abschnitt 7.1 entwickelte Serverschicht installiert werden:

Dies wird die Version 2 der Webversion unserer PAM-Anwendung sein.

Das NetBeans-Projekt für Version 1 ist das folgende Maven-Projekt:

  • in [1], die Konfigurationsdateien
  • in [2], die XHTML-Seiten und das Stylesheet
  • in [3], die [Web]-Schicht-Klassen
  • in [4], die zwischen der [Web]-Schicht und der [Business]-Schicht ausgetauschten Objekte sowie die [Business]-Schicht selbst
  • in [5], die Nachrichtendatei für die Internationalisierung der Anwendung
  • in [6], die Anwendungsabhängigkeiten

Wir werden einige dieser Elemente näher betrachten.

10.3.1. Konfigurationsdateien

Die Datei [web.xml] wird standardmäßig von NetBeans generiert, zusammen mit der Konfiguration für eine Ausnahmeseite:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">
 
  <!-- Apache CXF -->
  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  
 
  <!-- lower layers -->
  <import resource="classpath:spring-config-metier-dao.xml" />  
 
  <!-- web service -->
  <bean id="wsMetier" class="pam.ws.PamWsMetier">
    <property name="metier" ref="metier"/>
  </bean>
  <jaxws:endpoint id="wsmetier"
                  implementor="#wsMetier"
                  address="/metier">
  </jaxws:endpoint>  
 
</beans>
  • Zeile 30: [index.html] ist die Startseite der Anwendung
  • Zeilen 32–39: Konfiguration der Ausnahmeseite

Die Seite [exception.html] stammt aus [ref3]. Ihr Code lautet wie folgt:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>  
  <context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param> 
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>
  <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>
  <session-config>
    <session-timeout>
      30
    </session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
  </welcome-file-list>
  <error-page>
    <error-code>500</error-code>
    <location>/faces/exception.xhtml</location>
  </error-page>
  <error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/faces/exception.xhtml</location>
  </error-page>
</web-app>

Jede Ausnahme, die nicht explizit vom Code der Webanwendung behandelt wird, führt dazu, dass eine Seite ähnlich der unten gezeigten angezeigt wird:

Die Datei [faces-config.xml] sieht wie folgt aus:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
  <f:view locale="#{changeLocale.locale}">
    <h:head>
      <title>JSF</title>
      <h:outputStylesheet library="css" name="styles.css"/>
    </h:head>
    <h:body style="background-image: url('${request.contextPath}/resources/images/standard.jpg');">
      <h:form id="formulaire">
        <h3><h:outputText value="#{msg['exception.header']}"/></h3>
        <h:panelGrid columnClasses="col1,col2" columns="2" border="1">
          <h:outputText value="#{msg['exception.httpCode']}"/>
          <h:outputText value="#{requestScope['javax.servlet.error.status_code']}"/>
          <h:outputText value="#{msg['exception.message']}"/>
          <h:outputText value="#{requestScope['javax.servlet.error.exception']}"/>
          <h:outputText value="#{msg['exception.requestUri']}"/>
          <h:outputText value="#{requestScope['javax.servlet.error.request_uri']}"/>
          <h:outputText value="#{msg['exception.servletName']}"/>
          <h:outputText value="#{requestScope['javax.servlet.error.servlet_name']}"/>
        </h:panelGrid>
      </h:form>
    </h:body>
  </f:view>
</html>

Beachten Sie folgende Punkte:

  • Zeilen 9–14: Die Datei [messages.properties] wird für die Internationalisierung der Seite verwendet. Sie ist in XHTML-Seiten über den Schlüssel „msg“ zugänglich.
  • Zeile 15: Definiert die Datei [messages.properties] als vorrangige Quelle für Fehlermeldungen, die von den Tags <h:messages> und <h:message> angezeigt werden. Damit können Sie bestimmte Standard-JSF-Fehlermeldungen überschreiben. Diese Funktion wird hier nicht verwendet.

10.3.2. Das Stylesheet

Die Datei [styles.css] sieht wie folgt aus:

<?xml version="1.0" encoding="UTF-8"?>
<!-- =========== FULL CONFIGURATION FILE ================================== -->
<faces-config version="2.0"
              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_0.xsd">

  <application>
    <resource-bundle>
      <base-name>
        messages
      </base-name>
      <var>msg</var>
    </resource-bundle>
    <message-bundle>messages</message-bundle>
  </application>
</faces-config>

Hier sind einige Beispiele für JSF-Code, der diese Stile verwendet:


<h:outputText value="#{msg['form.infos.employee']}"
 styleClass="titleInfo"/>

<h:panelGrid columns="3"
rowClasses="label,info">

<h:message for="hoursWorked"
 styleClass="error"/>

10.3.3. Die Meldungsdatei

Die Meldungsdatei [messages_fr.properties] sieht wie folgt aus:


.libelle{
   background-color: #ccffff;
   font-family: 'Times New Roman',Times,serif;
   font-size: 14px;
   font-weight: bold
}
body{
   background-color: #ffccff
}
 
.error{
   color: #ff3333
}
 
.info{
   background-color: #99cc00
}
 
.titreInfos{
   background-color: #ffcc00
}

Diese Meldungen werden alle auf der Seite [index.xhtml] verwendet, mit Ausnahme derjenigen in den Zeilen 11–15, die auf der Seite [exception.xhtml] verwendet werden.

10.3.4. Der Geltungsbereich von Beans

Die Bean [web.forms.Form] hat einen Request-Gültigkeitsbereich:


form.titre=Feuille de salaire
form.comboEmployes.libell\u00e9=Employ\u00e9
form.heuresTravaill\u00e9es.libell\u00e9=Heures travaill\u00e9es
form.joursTravaill\u00e9s.libell\u00e9=Jours travaill\u00e9s
form.heuresTravaill\u00e9es.required=Indiquez le nombre d'heures travaill\u00e9es
form.heuresTravaill\u00e9es.validation=Donn\u00e9e incorrecte
form.joursTravaill\u00e9s.required=Indiquez le nombre de jours travaill\u00e9s
form.joursTravaill\u00e9s.validation=Donn\u00e9e incorrecte
form.btnSalaire.libell\u00e9=Salaire
form.btnRaz.libell\u00e9=Raz
exception.header=L'exception suivante s'est produite
exception.httpCode=Code HTTP de l'erreur
exception.message=Message de l'exception
exception.requestUri=Url demand\u00e9e lors de l'erreur
exception.servletName=Nom de la servlet demand\u00e9e lorsque l'erreur s'est produite
form.infos.employ\u00e9=Informations Employ\u00e9
form.employe.nom=Nom
form.employe.pr\u00e9nom=Pr\u00e9nom
form.employe.adresse=Adresse
form.employe.ville=Ville
form.employe.codePostal=Code postal
form.employe.indice=Indice
form.infos.cotisations=Informations Cotisations sociales
form.cotisations.csgrds=CSGRDS
form.cotisations.csgd=CSGD
form.cotisations.retraite=Retraite
form.cotisations.secu=S\u00e9curit\u00e9 sociale
form.infos.indemnites=Informations Indemnit\u00e9s
form.indemnites.salaireHoraire=Salaire horaire
form.indemnites.entretienJour=Entretien / Jour
form.indemnites.repasJour=Repas / Jour
form.indemnites.cong\u00e9sPay\u00e9s=Cong\u00e9s pay\u00e9s
form.infos.salaire=Informations Salaire
form.salaire.base=Salaire de base
form.salaire.cotisationsSociales=Cotisations sociales
form.salaire.entretien=Indemnit\u00e9s d'entretien
form.salaire.repas=Indemnit\u00e9s de repas
form.salaire.net=Salaire net

Der Bean [web.utils.ChangeLocale] hat den Anwendungsbereich:


import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
 
@ManagedBean
@RequestScoped
public class Form implements Serializable {

10.3.5. Die [Geschäfts-]Ebene

Die [Business]-Schicht implementiert die folgende IMetierLocal-Schnittstelle:


package web.utils;
 
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean
@SessionScoped
public class ChangeLocale implements Serializable{
  // page locale
  private String locale="fr";
 
  public ChangeLocale() {
  }
 
  public String setFrenchLocale(){
    locale="fr";
    return null;
  }
 
  public String setEnglishLocale(){
    locale="en";
    return null;
  }
 
  public String getLocale() {
    return locale;
  }
 
  public void setLocale(String locale) {
    this.locale = locale;
  }
 
 
}

Diese Schnittstelle wird auf der Serverseite der in Abschnitt 7.1 beschriebenen Client-Server-Anwendung verwendet.

Die Business-Klasse, die wir zum Testen der [Web]-Schicht verwenden werden, implementiert diese Schnittstelle wie folgt:


package metier;
 
import java.util.List;
import javax.ejb.Local;
import jpa.Employe;
 
@Local
public interface IMetierLocal {
  // get your payslip
  FeuilleSalaire calculerFeuilleSalaire(String SS, double nbHeuresTravaillées, int nbJoursTravaillés );
  // list of employees
  List<Employe> findAllEmployes();
}

Wir überlassen es dem Leser, diesen Code zu entschlüsseln. Beachten Sie die verwendete Methode: Um die Implementierung des EJB-Teils der Anwendung zu vermeiden, simulieren wir die [Business]-Schicht. Sobald die [Web]-Schicht als korrekt verifiziert ist, können wir sie durch die eigentliche [Business]-Schicht ersetzen.

10.4. Das Formular [index.xhtml] und seine Vorlage [Form.java]

Wir werden nun die XHTML-Seite des Formulars und ihr Modell erstellen.

Empfohlene Lektüre in [ref3]:

  • Beispiel #3 (mv-jsf2-03) für die Liste der Tags, die in einem Formular verwendet werden können
  • Beispiel #4 (mv-jsf2-04) für vom Modell gefüllte Dropdown-Listen
  • Beispiel #6 (mv-jsf2-06) zur Eingabevalidierung
  • Beispiel #7 (mv-jsf2-07) zur Handhabung der Schaltfläche [Löschen]

10.4.1. Schritt 1


Frage: Erstellen Sie das Formular [index.xhtml] und das dazugehörige Modell [Form.java], die zur Anzeige der folgenden Seite benötigt werden:


Die Eingabekomponenten lauten wie folgt:

Nr.
ID
JSF-Typ
Modell
Rolle
1
comboEmployees
<h:selectOneMenu>
String comboEmployeesValue
List<Employee> getEmployees()
enthält die Liste der Mitarbeiter im Format
„Vorname Nachname“.
2
hoursWorked
<h:inputText>
String gearbeiteteStunden
Anzahl der gearbeiteten Stunden – reelle Zahl
3
daysWorked
<h:inputText>
String daysWorked
Anzahl der Arbeitstage – Ganzzahl
4
btnSalary
<h:commandButton>
 
startet die Gehaltsberechnung
5
btnReset
<h:commandButton>
 
setzt das Formular auf seinen Ausgangszustand zurück
  • Die Methode getEmployees gibt eine Liste von Mitarbeitern zurück, die aus der [business]-Schicht abgerufen wurden. Bei den im Kombinationsfeld angezeigten Objekten ist das Attribut itemValue auf die Sozialversicherungsnummer des Mitarbeiters und das Attribut itemLabel auf eine Zeichenfolge gesetzt, die aus dem Vor- und Nachnamen des Mitarbeiters besteht.
  • Die Schaltflächen [Salary] und [Clear] sind vorerst nicht mit Ereignisbehandlungsroutinen verknüpft.
  • Die Gültigkeit der Eingaben wird überprüft.

Image

Testen Sie diese Version. Überprüfen Sie insbesondere, ob Eingabefehler korrekt markiert werden.

Hinweis: Es ist wichtig, dass die ID-Attribute der Seitenkomponenten keine Zeichen mit Akzenten enthalten. Bei Glassfish 3.1.2 führt dies zum Absturz der Anwendung.

10.4.2. Schritt 2


Frage: Vervollständigen Sie das Formular [index.xhtml] und dessen Vorlage [Form.java], damit die folgende Seite angezeigt wird, sobald die Schaltfläche [Salary] angeklickt wurde:


Die Schaltfläche [Gehalt] wird mit dem Ereignis-Handler „calculateSalary“ des Modells verknüpft. Diese Methode nutzt die Methode „calculatePaystub“ aus der [business]-Schicht. Diese Gehaltsabrechnung wird für den unter [1] ausgewählten Mitarbeiter erstellt.

Im Modell wird die Gehaltsabrechnung durch das folgende private Feld dargestellt:


package metier;
 
...
public class Metier implements IMetierLocal {
 
  // employee dictionary indexed by n° SS
  private Map<String,Employe> hashEmployes=new HashMap<String,Employe>();
  // list of employees 
  private List<Employe> listEmployes;
 
  // get your payslip
  public FeuilleSalaire calculerFeuilleSalaire(String SS,
    double nbHeuresTravaillées, int nbJoursTravaillés) {
    // we retrieve employee n° SS
    Employe e=hashEmployes.get(SS);
    // we make a fiictive payslip
    return new FeuilleSalaire(e,new Cotisation(3.49,6.15,9.39,7.88),new ElementsSalaire(100,100,100,100,100));
  }
 
  // list of employees
  public List<Employe> findAllEmployes() {
    if(listEmployes==null){
      // create a list of two employees
      listEmployes=new ArrayList<Employe>();
      listEmployes.add(new Employe("254104940426058","Jouveinal","Marie","5 rue des oiseaux","St Corentin","49203",new Indemnite(2,2.1,2.1,3.1,15)));
      listEmployes.add(new Employe("260124402111742","Laverti","Justine","La brûlerie","St Marcel","49014",new Indemnite(1,1.93,2,3,12)));
      // employee dictionary indexed by n° SS
      for(Employe e:listEmployes){
        hashEmployes.put(e.getSS(),e);
      }
    }
    // we return the list of employees
    return listEmployes;
  }
}

die über Get- und Set-Methoden verfügt.

Um die in diesem Objekt enthaltenen Informationen abzurufen, können Sie in der JSF-Seite Ausdrücke wie die folgenden schreiben:


  private FeuilleSalaire feuilleSalaire;

Der Ausdruck im Attribut „value“ wird wie folgt ausgewertet:

[form].getPayrollSheet().getEmployee().getName(), wobei [form] eine Instanz der Klasse [Form.java] darstellt. Der Leser kann überprüfen, ob die hier verwendeten get-Methoden tatsächlich in den Klassen [Form], [PayrollSheet] bzw. [Employee] vorhanden sind. Wäre dies nicht der Fall, würde bei der Auswertung des Ausdrucks eine Ausnahme ausgelöst werden.

Testen Sie diese neue Version.

10.4.3. Schritt 3


Frage: Vervollständigen Sie das Formular [index.xhtml] und dessen Vorlage [Form.java], um die folgenden zusätzlichen Informationen zu erhalten:


Wir werden denselben Ansatz wie zuvor verfolgen. Es gibt beispielsweise ein Problem mit dem Euro-Währungssymbol in [1]. In einer internationalisierten Anwendung wäre es vorzuziehen, das Anzeigeformat und das Währungssymbol der ausgewählten Ländereinstellung (en, de, fr, ...) zu verwenden. Dies lässt sich wie folgt erreichen:


<h:outputText value="#{form.feuilleSalaire.employe.nom}"/>

Wir hätten auch schreiben können:


          <h:outputFormat value="{0,number,currency}">
            <f:param value="#{form.feuilleSalaire.employe.indemnite.entretienJour}"/>
</h:outputFormat>

Bei der Locale „en_GB“ (britisches Englisch) würde der Betrag jedoch weiterhin in Euro angezeigt, obwohl er in Pfund (£) angegeben sein sollte. Mit dem Tag <h:outputFormat> können Informationen entsprechend der Locale der angezeigten JSF-Seite dargestellt werden:

  • Zeile 1: Zeigt den Parameter {0} an, bei dem es sich um eine Zahl handelt, die einen Geldbetrag darstellt
  • Zeile 2: Das <f:param>-Tag weist dem Parameter {0} einen Wert zu. Ein zweites <f:param>-Tag würde dem Parameter mit der Bezeichnung {1} einen Wert zuweisen und so weiter.

10.4.4. Schritt 4

Empfohlene Lektüre: Beispiel Nr. 7 (mv-jsf2-07) in [ref3].


Frage: Vervollständigen Sie das Formular [index.xhtml] und dessen Vorlage [Form.java], um die Schaltfläche [Reset] zu implementieren.


Die Schaltfläche [Reset] versetzt das Formular in den Zustand zurück, in dem es sich befand, als es erstmals über eine GET-Anfrage abgerufen wurde. Hier gibt es mehrere Herausforderungen. Einige davon wurden in [ref3] erläutert.

Das vom [Raz]-Button zurückgegebene Formular ist nicht das gesamte Formular, sondern nur der bereits ausgefüllte Teil davon:

Image

Dieses Ergebnis lässt sich wie folgt mit einem <f:subview>-Tag erzielen:


          <h:outputText value="#{form.feuilleSalaire.employe.indemnite.entretienJour} є">

Das <f:subview>-Tag umschließt den gesamten Teil des Formulars, der ein- oder ausgeblendet werden kann. Jede Komponente kann mithilfe des Attributs „rendered“ ein- oder ausgeblendet werden. Wenn „rendered“ den Wert „true“ hat, wird die Komponente angezeigt; wenn „rendered“ den Wert „false“ hat, wird sie nicht angezeigt. Wenn das Attribut „rendered“ seinen Wert aus dem Modell bezieht, kann die Anzeige der Komponente programmgesteuert geregelt werden.

Im obigen Beispiel steuern wir die Anzeige der Ansicht „viewInfos“ mithilfe des folgenden Feldes:


      <f:subview id="viewInfos" rendered="#{form.viewInfosIsRendered}">
... la partie du formulaire qu'on veut pouvoir ne pas afficher
</f:subview>

zusammen mit seinen Get- und Set-Methoden. Die Methoden, die Klicks auf die Schaltflächen [Gehalt] und [Löschen] verarbeiten, aktualisieren diesen booleschen Wert je nachdem, ob die Ansicht „viewInfos“ angezeigt werden soll oder nicht.