Tutorial Webentwicklung (mit JSF) – Applikation “Rezensionen”, Teil I

In meinem Blog liste ich u.a. die von mir rezensierten Bücher. Dabei wird jedes Buch in tabellarischer Form aufgeführt.

Zu jedem Buch werden diese Informationen dargestellt:

  • Titel
  • Untertitel
  • Autor(en)
  • Verlag
  • Jahr
  • Sprache
  • ISBN
  • Kurztext
  • Verweis auf die Rezension(en)

Die Pflege erfolgt manuell und muss in jeder Kategorie bzw. Anzeigesprache eigens erstellt werden. Eine Änderung der Darstellung ist mit hohem Aufwand verbunden.

Es soll nun eine mehrsprachige Anwendung zur Darstellung der rezensierten Bücher entwickelt werden. Ziel ist, die Bücher in unterschiedlichen Anzeigesprachen sowie in unterschiedlichen Kategorien darzustellen. Dabei soll ein Buch durch Zufügen einer Kategorie in derselben gelistet werden. Die Darstellung selbst soll austauschbar gestaltet werden. Sie wird an zentraler Stelle gepflegt und automatisch für alle Bücher genutzt.
Continue reading “Tutorial Webentwicklung (mit JSF) – Applikation “Rezensionen”, Teil I”

JSF, Pflichfelder markieren

Kennen Sie dies nicht? Sie haben eine Applikation mit diversen Dialogen, in denen jeweils sowohl Pflicht- als auch optionale Felder enthalten sind. Damit diese beiden Typen für den Anwender unterscheidbar sind, sollen die Pflichfelder markiert werden. Und dass ganze an einer zentralen Stelle, z.B. als Teil eines Templates. Die dahinter liegende Idee ist recht einfach: Vor der Auslieferung an den Browser werden alle Label geprüft, ob die zugehörigen Eingabefelder Pflicht sind. Falls ja, erfolgt die Markierung. Continue reading “JSF, Pflichfelder markieren”

Tutorial Webentwicklung (mit JSF) VII: Backstage

Backstage

[Dieser Artikel ist noch in Bearbeitung und daher unvollständig]

Bei einer traditionellen Anwendung ist es in der Regel so, dass die Applikation selbst für die Darstellung verantwortlich ist. Auch wenn Sie dafür eines Severdienstes wie X bedienen sollte, so obliegt die Steuerung dennoch dem Programm.

Anders bei einer Webapplikation. Hier werden die Daten an einen Browser übergeben, der sich um die Darstellung kümmert. Dazu verpackt der Server den darzustellenden Inhalt in ein (X)HTML-Dokument. Daneben kann der Server noch ein paar Darstellungsinformationen in Form von CSS mitliefern. Alles Weitere ist dann Sache des Browsers. Und so wie es unterschiedliche Browser gibt, kann sich auch die Darstellung unterscheiden. Die stetige Weiterentwicklung der Standards sorgt hier glücklicherweise für eine allmähliche Angleichung. Hält hier der Anwender aber ein lokales CSS vor, so kann die Darstellung wieder anders ausfallen.

Nicht nur, dass eine Webapplikation die Ausgabe an den Browser delegiert; sie wird auch nicht von selbst aktiv! Erst wenn der Anwender via Browser eine Seite anfordert, so liefert die Applikation eine solche aus. Die (scheinbar) aktive Änderung von Inhalten aufgrund von severseitiger Verarbeitung geht nicht ohne weitere Hilfsmittel. Hier lautet das Stichwort AJAX (Asynchronous JavaScript and XML). Womit wir neben (X)HTML und CSS bei einer weiteren browserseitigen Technik angelangt sind: JavaScript. Der Browser fordert zwischendurch mittels JavaScript immer wieder mal mittel pertiellem Request ein paar Daten an und tauscht Teile des Browserinhalts aus. Somit entsteht zumindest zum Teil der Eindruck, der Server aktualisiere den Bildschirm. Tatsächlich geht hier aber immer wieder eine Anfrage vom Client aus (pull). Ein echtes Push, also die vom Server veranlasste aktive Änderung der Darstellung erfordert einen tieferen Griff in die Trickkiste. Hier wird die Antwort an den Client künstlich verzögert, um zu einem späteren noch Informationen übermitteln zu können. Doch dies ist etwas für einen späteren Teil.

Bei einer traditionellen Applikation kann das Programm sofort auf eine Anwendereingabe reagieren. Bei einer Webapplikation bekommt das Programm erst dann etwas von den Anwendereingaben mit, wenn eine neue Seite oder – meist in Verbindung mit AJAX – patriell eine neue Seite angefordert wird. Zu diesem Zeitpunkt können bereits Eingaben in diversen Feldern erfolgt sein. Nicht schwer vorzustellen, dass die Applikation hiermit etwas anders umgehen muss. An dieser Stelle unterstützt JSF den Anwender und löst auf dem Server für die einzelnen Eingaben entsprechende Events aus, so dass sich ein dem Entwickler nicht ganz fremdes Programmiermodell ergibt.

Und noch ein Unterschied: Eine Webapplikation läuft meist in einer Ablaufumgebung, die ihr zahlreiche Dienste zur Verfügung stellt. Eine solche Ablaufumgebung wird als Container beszeichnet, im Falle von JSF ist dies ein sogenannter Servlet-Container. Dies deutet auf die zugrunde liegende Technik der Servlets hin. Auch bei der Entwicklung mit JSF kann die direkte Nutzung von Servlets hier und da angebracht sein. Es kann also nicht schaden, wenn Sie sich auch mit dieser Technik vertraut machen. Mehr dazu in einem späteren Teil.

Der Servlet -Container versorgt die Applikation mit Schnittstellen zu anderen Diensten. Er ist Bestandteil eines Applikations- oder auch Webservers. Zahlreiche Server beinhalten im Wesentlichen einen Container und so werden die Begriffe Container und Applikationsserver häufig synonym genutzt. Tatsächlich kann ein Server jedoch mehrere Container beherrbergen. So z.B., GlassFish, der neben Dem Servlet-Container u.a. Auch einen EJB-Container beherrbergt. Im Folgenden schauen wir von außen auf den Applikationsserver.

Wenn nun ein Anwender die Web-Applikation nutzen möchte, so ruft er in seinem Browser die URL der Anwendung auf. Der Client startet eine Anfrage an den Server. Dieser erkennt anhand der URL, dass er nicht einfach eine statische Seite ausliefern muss, sondern leitet die Anfrage über den Container an die Applikation weiter. Dort wird diese verarbeitet. Die Ausgabe wird als (X)HTML-Dokument genertiert und an den Browser verschickt. Dieser zeigt die Daten an.

<Abbildung fehlt noch>

Bei dieser Sichtweise betrachten wir den ApplicationServer al BlockBox. Interessant ist aber auch, was darin passiert. Erinnern Sie sich kurz an die bisherigen Anwendungen: Hier haben Sie jeweils eine JSF-Seite definiert. Als Seitensprache wurden Facelets eingesetzt. Jede Seite bestand neben HTML auch aus bestimmten Tags, wie beispielsweise “f:InputText”. Im Browser haben jeweils die URL einer solchen Seite angegeben. Entweder direkt oder indirekt als Angabe der Applikations-URL, die aber intern auf eine konkrete Seite verwiesen hat.

Der Server bestimmt anhand der URL die darzustellende Seite, analysiert deren Inhalt und löst die Tags auf. Im einfachsten Fall werden diese durch entsprechende Daten ersetzt. Die so entstandene Seite wird an den Browser geschickt. Dies ist aber lediglich eine vereinfachte Darstellung. Der Browser könnte ja bereits vorher Daten der Aplikation angezeigt haben. Daher prüft JSF als erstes, ob bereits eine Session besteht. Falls ja wird der Komponentenbaum, die logische Abbildung der dazustellenden Inhalte, wieder hergestellt. Eingaben werden validiert und Datenfelder upgedatet. Insgesamt unterscheidet hier JSF sechs verschiedene Phasen.

Tutorial JSF, NetBeans 7.1

Im letzten Teil meines Tutorials habe ich angedeutet, wie es weitergeht. Nun, zwischenzeitlich habe ich einen neuen Editor genutzt, und dieser hat mir die Quelltexte in den bisherigen Tutorien “zerschossen”. Diese habe ich nun wieder hergestellt und bin zudem dabei, die bisherigen Teile erst einmal ins Englische zu übersetzen.

Des Weiteren steht die Version 7.1 von NetBeans vor der Tür. Hier arbeite ich aktiv an der Prüfung der Version mit. Auch hierfür benötige ich ein “wenig” Zeit. Insofern bitte ich noch um ein bisschen Geduld, bevor ich den nächsten Teil des Tutorials erstelle.

Tutorial Webentwicklung (mit JSF) VI: Schablonen

Schablonen

Im voherigen Teil dieses Tutorials haben wir eine zweite Seite erstellt, die in ihrem Aufbau der ersten gleicht. Nun geht es darum, die gemeinsamen Teile auch gemeinsam zu nutzen. Wir werden daher eine Schablone (template) erstellen, welche die gemeinsamen Elemente enthält und in die von den einzelnen Seiten einfach der individuelle Teil hinein kopiert wird.

Zur Erinnerung, hier nochmals der Quelltext der beiden Seiten:
Continue reading “Tutorial Webentwicklung (mit JSF) VI: Schablonen”

Tutorial Webentwicklung (mit JSF) V: Szenenwechsel

Szenenwechsel

Der einfache Rechner funktioniert soweit ganz gut. Nach Eingabe der beiden Parameter und Betätigung einer der Schaltflächen für die Grundrechenarten wird das Resultat unmittelbar darunter ausgegeben. Dies ist gut so, soll der Anwender doch auf der Seite bleiben und weiter rechnen. Es gibt aber durchaus Anwendungen, die aus einer Vielzahl von Seiten bestehen. Denken Sie beispielsweise an ein Buchungsystem oder einen Shop. Nach Abschluß der gewünschten Transation erhalten Sie meist eine Buchungsbestätigung auf einer separaten Seite. Dies möchte ich Ihnen anhand unseres Rechners demonstrieren: Das Ergebnis der Addition wird auf einer separaten Seite angezeigt. Von dort können Sie per Knopfdruck wieder zum Rechner gelangen. Nicht unbedingt anwenderfreundlich, aber hier geht es ja darum, erste Möglichkeiten der Seitennavigation kennen zu lernen.

Continue reading “Tutorial Webentwicklung (mit JSF) V: Szenenwechsel”

Tutorial Webentwicklung (mit JSF)

Nun habe ich schon eine ganze Weile keinen Artikel zu meinem Tutorial verfasst. Wer meine Kurznachrichten auf Twitter verfolgt hat, ist informiert, dass ich momentan am Institut ein hohes Arbeitsaufkommen zu bewältigen habe. Dennoch möchte ich ein aktuelles Feedback von Andreas Schlappig, der das Tutorial als hilfreich bezeichnet hat (obwohl es erst ein paar Grundlagen aufzeigt) und mich auf einige Tippfehler aufmerksam machte, zum Anlass nehmen, hier kurz mitzuteilen, wann es weiter geht: Voraussichtlich ab Mitte April kann ich wieder ein wenig am Tutorial arbeiten. Und ich hoffe, dass dies mit der Vertiefung des Themas weiterhin interessant bleibt.

Tutorial Webentwicklung (mit JSF) IV: Stylen

Stylen

Nun, unser Rechner beherrscht die vier Grundrechenarten, aber auf dem Bildschirm sieht das Ganze etwas gedrängt aus. Es gilt also, die Oberfläche zu gestalten. Und wie geschieht dies heutzutage, wenn nicht mit CSS? Jetzt kommt aber kein Kurs zum Webdesign. Ich möchte lediglich zeigen, wie dies in Verbindung mit JSF geschieht.

Zur Anlage eines CSS stellt NetBeans einen passenden Assistenten zur Verfügung. Nach einem Rechtsklick auf das Projekt TinyCalculator wählen Sie New->Other und im darauffolgenden Dialog aus dem Bereich Web das Cascading Style Sheet.

Continue reading “Tutorial Webentwicklung (mit JSF) IV: Stylen”

Tutorial Webentwicklung (mit JSF) III: Grundrechenarten

Grundrechenarten

Nun, die Grundrechenarten kennt (hoffentlich) doch jeder: Addieren, Subtrahieren, Multiplizieren und Dividieren. Dazu braucht es zwei Zahlen, die mit einem der vier Operatoren verknüpft werden und der Rechner spuckt das Ergebnis aus. Eine triviale Aufgabe, die Sie wahrscheinlich auch im Kopf oder schriftlich lösen können, aber warum die Mühe? Lassen wir dies unseren Computer erledigen und zwar so, dass wir dies im Browser nutzen können.

In diesem Teil des Tutorials lernen Sie die unter anderem serverseitige Verarbeitung mittels einer sogeannten managed Bean kennen.

Legen Sie dazu wahlweise ein neues Web-Projekt, wie unter “Die erste Webapplikation” beschrieben an, mit dem Unterschied, dass Sie das Projekt “TinyCalulator” nennnen oder nennen Sie das vorhandene Projekt um. Für Letzteres klicken Sie in der Projektansicht mit der sekundären (meist rechten) Maustaste auf das Projekt “JSFTutorial” und wählen im Popupmenü “Rename…”. Es erscheint ein kleiner Dialog zum Umbennen des Projekts:

   

Wählen Sie als neuen Namen “TinyCalculator” und markieren “Also Rename Project Folder”, um den Ordner gleichlautend umzubenennen.

Nun, was benötigen Sie für dieses Projekt? Da sind zwei Eingabefelder für die beiden Parameter, vier Buttons für die Operatoren und ein Feld für das Ergebnis. Editieren Sie dazu den Sourcecode der Seite index.xhtml

       

Die Abbildung zeigt dies im Kontext von NetBeans. Für die weitere Beschreibung verzichte ich auf solche Abbildungen. Stattdessen finden Sie jeweils den Sourcecode gelistet. So auch hier, um diesen einfach mittels copy and paste zu übernehmen (der Lerneffekt ist aber größer, wenn Sie selber editieren).

<?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">
    <h:head>
        <title>Tiny calculator</title>
    </h:head>
    <h:body>
        <h1>Tiny calculator</h1>
        <h:form>
            <h:outputLabel value="Param 1:"/>
            <h:inputText id="param1"/>
            <br/>
            <h:outputLabel value="Param 2:"/>
            <h:inputText id="param2"/>
            <br/>
            <h:commandButton value="add"/>
            <h:commandButton value="substract"/>
            <h:commandButton value="multiply"/>
            <h:commandButton value="divide"/>
            <br/>
            <h:outputLabel value="Result:"/>
            <h:outputText id="result"/>
        </h:form>
    </h:body>
</html>

Wie Sie erkennen können, gibt es neben ein paar beschreibenden Labeln die erforderlichen Komponenten (inputText, commandButton und outputText). Gerechnet wird an dieser Stelle noch nicht. Starten Sie die Applikation.

               

In den beiden Eingabefeldern können Sie Werte eingeben. Klicken Sie auf einer der Schaltflächen, so scheint nicht zu passieren. Wenn Sie jedoch genau darauf achten, werden Sie bemerken, dass die Seite neu geladen wird.

Nun schauen Sie sich einmal den Sourcecode der Seite an (hier ein bisschen “schöner” formatiert).

<?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">
  <head>
    <title>Tiny calculator</title>
  </head>
  <body>
    <h1>Tiny calculator</h1>
    <form id="j_idt8" name="j_idt8" method="post" 
            action="/TinyCalculator/index.xhtml" 
            enctype="application/x-www-form-urlencoded">
      <input type="hidden" name="j_idt8" value="j_idt8" />
      <label>Param 1:</label>
      <input id="j_idt8:param1" type="text" name="j_idt8:param1" />
      <br />
      <label>Param 2:</label>
      <input id="j_idt8:param2" type="text" name="j_idt8:param2" />
      <br />
      <input type="submit" name="j_idt8:j_idt13" value="add" />
      <input type="submit" name="j_idt8:j_idt14" value="substract" />
      <input type="submit" name="j_idt8:j_idt15" value="multiply" />
      <input type="submit" name="j_idt8:j_idt16" value="divide" />
      <br />
      <label>Result:</label>
      <span id="j_idt8:result"></span>
      <input type="hidden" name="javax.faces.ViewState" 
            id="javax.faces.ViewState" 
            value="3061588258500397437:-7913731195929753954" 
            autocomplete="off" />
    </form>
  </body>
</html>

Hier ist bereits deutlich mehr passiert als in der ersten Applikation. Und es wird Zeit, zumindest ein paar der Ersetzungen genauer unter die Lupe zu nehmen.

Unser Quelltext

<h:head>
   <title>Tiny calculator</title>
</h:head>

erreicht den Browser als

<head>
    <title>Tiny calculator</title>
</head>

Das haben Sie bereits bei der ersten Applikation gesehen. Was passiert eigentlich, wenn Sie das Präfix “h:” einfach auslassen? Nun, hier erst einmal nichts: Der Browser erhält zur Darstellung den gleichen HTML-Code. Später werden Sie jedoch sehen, dass es Komponenten gibt, die in den Header gehören. Und ohne den Namensraum zur Kennzeichnung als Tag, weiß JSF dann damit nichts anzufangen. Geben Sie den Präfix also einfach immer an. Er schadet nicht, und wenn Sie ihn brauchen,ist er da. Entsprechendes gilt auch für den Body.

Deutlich mehr passiert bereits bei “h:form”

<h:form> 
    [...] 
</h:form>

Im Browserquelltext wird dies regelrecht aufgebläht.

<form id="j_idt8" name="j_idt8" method="post" 
        action="/TinyCalculator/index.xhtml" 
        enctype="application/x-www-form-urlencoded">
  <input type="hidden" name="j_idt8" value="j_idt8" />
[...]
  <input type="hidden" name="javax.faces.ViewState" 
        id="javax.faces.ViewState" 
        value="3061588258500397437:-7913731195929753954" 
        autocomplete="off" />
</form>

Da ist zum einen eine id. Diese können Sie auch selber festlegen. Sie muss für die Seite eindeutig sein und dient dem serverseitigen Aufbau des Komponentenbaums. Interessant sind auch zwei versteckte Eingabefelder, die JSF nutzt, um Informationen mitzuführen. So müssen die Status der einzelnen Komponenten zwischengespeichert werden. Dies geschieht je nach Konfiguration auf dem Server oder auf dem Client. Der Wert des versteckten Eingabefeldes mit der ID “javax.faces.ViewState” stellt einen Identifier dar, unter dem die Status serverseitig gespeichert werden. Er ändert sich bei jedem Aufruf. Bei clientseitiger Speicherung kann der Wert je nach Größe des Formulars deutlich größer ausfallen. Weitergehende Informationen finden Sie in späteren Teilen dieses Tutorials beim JSF-Lebenszyklus sowie der Konfiguration

Der Rest im Schnelldurchgang: Ein outputLabel wird in ein label übersetzt, ein inputText in input type “text”, ein commandButton in input type “submit” sowie der outputText in ein span. In dieser Applikation. Denn je nach Kontext können einzelne Komponenten auch schon einmal anders übersetzt werden. Insofern stellen diese Tags ein Abstraktion von HTML-Elementen dar. Und jede Komponente erhält eine eindeutige ID bzw. Namen, in dem sich die Schachtelung der Komponenten widerspiegelt.

Eine Menge Stoff bisher, und die Anwendung kann noch nicht einmal rechnen. Zum Glück fällt der Quelltext bisher recht übersichtlich aus. Und vielmehr wird es auch nicht. Denn die Berechnung hat nichts in der xhtml-Seite zu suchen, schließlich erfolgt sie serverseitig. Aber wo?

Nun, dazu benötigt es eine Kaffeebohne (JavaBean). Eine JavaBean zeichnet sich dadurch aus, dass der Zugriff auf die Attribute (Objektvariablen) einem bestimmten Schema folgt, nämlich getund set, wobei Siedurch den gewünschten Methodennamen (in Anlehnung an das jeweilige Attribut ersetzen. Auch bekannt als Getter/Setter.

Legen Sie dazu eine neue Klasse vom Typ “JSF Managed Bean” an.

                                                       

Geben Sie als Klassennamen “CalculatorBean” an. Diesen Namen finden Sie weiter unten – mit kleinem Anfangsbuchstaben – als Name wieder.

               

Unter “Package” vergeben Sie einen beliebigen Paketnamen, im Beispiel “calculator”. Eine interessante Einstellung können Sie bei “Scope” vornehmen. Damit legen Sie fest, ob die Bean beispielsweise nur für eine Anfrage, eine Sitzung oder die gesamte Applikation gültig ist. Mehr dazu später. Belassen Sie dies hier auf “request” und beenden Sie den Assistenten mit [Finish]. Der Assistent legt Ihnen nun die Klasse an sowie diverse Einträge in den Konfigurationsdateien, die ich später erkläre. Sollten Sie einmal eine “normale” Java-Klasse anlegen, müssen Sie all diese Einstellungen manuell vornehmen, um sie als JSF Managed Bean nutzen zu können. Ein Lob auf den Assistenten 😉

Vervollständigen Sie den Quelltext wie folgt:

package calculator;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

/**
 *
 * @author mmueller
 */
@ManagedBean
@RequestScoped
public class CalculatorBean {
    private int _param1;
    private int _param2;
    private String _result;

    public CalculatorBean() {
    }

    // 
    public int getParam1() {
        return _param1;
    }

    public void setParam1(int param1) {
        _param1 = param1;
    }

    public int getParam2() {
        return _param2;
    }

    public void setParam2(int param2) {
        _param2 = param2;
    }

    public String getResult() {
        return _result;
    }
    // 

    public String add(){
        _result = Integer.toString(_param1 + _param2);
        return "";
    }

    public String substract(){
        _result = Integer.toString(_param1 - _param2);
        return "";
    }

    public String multiply(){
        _result = Integer.toString(_param1 * _param2);
        return "";
    }

    public String divide(){
        _result = _param2 == 0 ? "n/a" : Double.toString(_param1 / (double)_param2);
        return "";
    }

}

Zwei Attribute entsprechen unseren Parametern und das dritte ist das Ergebnis. Das Ergebnis wird in vier Methoden, die wie die Grundrechenarten heißen berechnet und im Attribut abgelegt. Das sieht ungewöhnlich aus, geben Sie doch normalerweise das Ergebnis als Rückgabewert der Methode (Funktion) aus. Hier liefern die Methoden stattdessen einen Leerstring (es darf auch null sein). Weiterhin fallen zwei Annotationen auf, die Ihre Eingaben im Assistenten wiederspiegeln. Wozu das Ganze gut ist, sehen Sie in Kürze. Wenn Sie möchten, schreiben Sie jetzt einen Unit-Test, um die Funktion der Bean zu überprüfen.

Wenden wir uns wieder der Webseite zu. Ergänzen Sie den Quelltext entsprechend dem folgenden Listing.

<?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">
    <h:head >
        <title>Tiny calculator</title>
    </h:head>
    <h:body>
        <h1>Tiny calculator</h1>
        <h:form id="calculator">
          <h:outputLabel for="param1" value="Param 1:"/>
          <h:inputText id="param1" value="#{calculatorBean.param1}"/>
          <br/>
          <h:outputLabel for="param2" value="Param 2:"/>
          <h:inputText id="param2" value="#{calculatorBean.param2}"/>
          <br/>
          <h:commandButton action="#{calculatorBean.add}" value="add"/>
          <h:commandButton action="#{calculatorBean.substract}" value="substract"/>
          <h:commandButton action="#{calculatorBean.multiply}" value="multiply"/>
          <h:commandButton action="#{calculatorBean.divide}" value="divide"/>
          <br/>
          <h:outputLabel for="result" value="Result:"/>
          <h:outputText id="result" value="#{calculatorBean.result}"/>
        </h:form>
    </h:body>
</html>

Zum einen erhalten Formular und Texte eine ID und die Labels werden daran gebunden. Diese Ids ersetzen die automatisch generierten und sind für den Entwickler deutlich besser zu lesen.

Zum anderen werden die Texte an die Getter/Setter gebunden. Nun, die Wertebindung kann in beide Richtungen erfolgen, und so wird einfach nur der Methodenname ohne “get” oder “set” angegeben. Dies wird intern automatisch ergänzt (genauer gesagt kommt hier Reflection zum Einsatz). Vielleicht kennen Sie die Properties aus C#? Ohne get/set sieht dies den Properties doch sehr ähnlich. Und wenn Sie sich Microsofts CLR ansehen, so werden Sie feststellen, dass die Properties intern mittels Getter und Setter realisiert sind. Oh wundersame Welt der Sprachen…

Und die Buttons werden an die Rechenmethoden gebunden. Sie sind nur der Auslöser, um die entsprechenden Methoden aufzurufen. Das Ergebnis wiederum ist als Wert (getter!) an den outputText gebunden. Zur Bindung dienen die Ausdrücke in der Form “#{…}”. Diese sind in der sogenannten Expression Language verfasst. Davon später mehr. Hier das Resultat der bisherigen Arbeit (Starten Sie die App mit F6).    

               

Das sieht wie gehabt aus. Wenn Sie nun aber Werte eingeben und einen der Buttons betätigen, so wird tatsächlich gerechnet.

Und wie von Zauberhand werden unpassende Eingaben kommentiert und abgewiesen.

               

Doch das ist eine andere Geschichte und davon erzähle ich später…

Tutorial Webentwicklung (mit JSF) II

Die erste Webapplikation

Im Folgenden wird eine rudimentäre Webapplikation erstellt – und zwar nur soweit, wie sie als Grundgerüst von Netbeans generiert wird. Weitere Funktionalität wird noch nicht zugefügt. Und doch liefert dieser Einstieg wichtige Grundlagen.

Sie können das Beispiel wahlweise an Ihrem Rechner nachvollziehen – oder aber einfach den Screenshots folgen, abhängig von Ihrer persönlichen Vorliebe zum Erlernen neuer Technologien.

Nach dem Start von NetBeans wählen ein neues Projekt (Tastenkombination {Strg}+{Umschalt}+{N}). Es erscheint der folgende Dialog, in dem Sie “Java Web” und daraus “Web Application” wählen. Der Dialog kann bei Ihnen eventuell etwas anders aussehen, je nachdem, welche (Sprach-) Version von NetBeans und welches Betriebssystem Sie nutzen.

Betätigen Sie die Schaltfläche [Next]. Im folgenden Dialog wählen Sie einen passenden Projektnamen, hier “JSFTutorial”. Soweit Sie Ihre Projekte in einem anderen Verzeichnis als dem vorgeschlagenen Standard ablegen möchten, passen Sie noch das Projektverzeichnis (Project Location) an. Weiter geht es wieder mit [Next].

Soweit Sie NetBeans ab Version 6.9 in der Standard-Konfiguration nutzen, sollte bei Ihnen im folgenden Dialog der GlassFish Sever 3.0 oder jünger voreingestellt sein. Sofern Sie noch eine ältere Version nutzen, ist jetzt der ideale Zeitpunkt für ein Update gekommen. Für die Beispiele in diesem Buch wird die Java Enterprise Edition in der Version 6 genutzt.

 

Wie Sie erkennen können, bietet Ihnen der Dialog die Möglichkeit, Context und Dependency Injection (CDI) nutzen zu können. Damit versetzen Sie den Application Server in die Lage, Objekte in Ihre Applikation zu “injizieren”. Mittels einer einfachen Annotation weisen Sie so den Server an, Ihnen innerhalb einer sogenannten Bean Referenzen auf bestimmte Objekte zur Verfügung zu stellen. Die Lebensdauer einer solchen Bean können Sie festlegen, sei es, dass sie für eine Anfrage, eine Sitzung oder sonstiges gilt. Auch mit JSF können Sie die Lebensdauer einer Bean festlegen. Leider verhalten sich CDI und JSF hier leicht unterschiedlich, so dass wir dieses starke Feature vorerst nicht nutzen.

Mittels Context Path geben Sie an, unter welchem Pfad die Applikation angesprochen wird. Dieser ist mit dem Projektnamen vorbelegt und Sie können dies so belassen. Bei Bedarf lässt sich der Pfad zu einem späteren Zeitpunkt auch wieder ändern.

Wie gewohnt geht es weiter mit [Next].

In diesem Dialog wählen Sie die JavaServerFaces als Framework. Darunter erscheint ein Tabulator-Element zur Konfiguration. Ein JEE6 kompatibler Server wie GlassFish verfügt bereits über die passenden Bibliotheken und so können Sie diese Vorreinstellung belassen. Bei Nutzung eines anderen Servers, z. B. Apache Tomcat, müssen Sie ggf. Die JSF-Bibliotheken mit bereitstellen. In einem solchen Fall wählen Sie “Registered Libraries”. Bevor Sie den Dialog abschließen, wählen Sie noch den Reiter “Configuration” und ändern das URL Pattern auf “*.xhtml”. NetBeans schlägt hier standardmäßig “/faces/*” vor. Dies führt dazu, dass der Pfad im Browser scheinbar um ein Verzeichnis länger wird. Der Funktionalität tut dies keinen Abbruch. Hier müssen Sie selber entscheiden.

Die bevorzugte Seitensprache ist mit “Facelets” vorbelegt. Alternativ ist auch “JSP” (Java Server Pages) möglich. In beiden Fällen werden bestimmte Namensräume bzw. Bibliotheken (Tag Libraries) eingebunden, die es Ihnen ermöglichen, spezielle Anweisungen in der HTML-Seite unterzubringen, die serverseitig vor Auslieferung an den Browser abgearbeitet werden. JSP existieren schon länger und waren bis JSF 1.2 die Standard-Seitensprache. Sie haben jedoch einen etwas anderen Lebenszyklus als JSF. Facelets wurden dagegen speziell für JSF entwickelt und sind seit JSF 2 Teil der Spezifikation und bevorzugte Seitensprache.

Nun ist genug gewählt und Sie beenden den Dialog mittels [Finish].

Daraufhin generiert NetBeans ein vollständig lauffähiges Projekt und öffnet die Seite Index.xhtml im Sourcecode-Editor.

Wie an der Deklaration zu erkennen, handelt sich dabei um eine XHTML-Seite. Im öffnenden HTML-Tag ist entsprechend der Namensraum für xhtml angegeben und zusätzlich der Namensraum für jsf/html. Dieser erhält traditionell das Präfix “h”. Eine erste Nutzung erkennen Sie in den Tags für head und body. Hier ist dieses Präfix vorangestellt. Vor Auslieferung der Seite wird dies verarbeitet – und dabei werden diese Tags einfach durch die Standard-HTML-Tags ersetzt. Insofern passiert hier nichts Aufregendes.

Auf der linken Seite erkennen Sie im Projekt-Tree, dass NetBeans Ihnen neben dieser Seite auch einige Konfigurationsdateien, die weiter unten beschrieben werden, generiert hat. Des Weiteren wurden die benötigten Bibliotheken in das Projekt eingebunden. Kurz, es ist alles vorhanden, um das Projekt starten zu können. Dies geschieht mittels {F6}.

Der erste Start dauert etwas länger. NetBeans startet GlassFish, stellt die Applikation bereit und startet diese. Das Bereitstellen der Applikation wird als “Deploy” bezeichnet. Dies alles erledigt NetBeans für Sie. In einer produktiven Umgebung werden Sie jedoch nicht den lokalen Server nutzen – und den Server schon gar nicht jeweils neu starten. Hier müssen Sie vielmehr manuell deployen oder scripten – wie dies vonstatten geht, erfahren Sie in einem späteren Teil des Tutorials.

Nachdem der Server gestartet wurde, ruft NetBeans den Browser auf. Das Ergebnis ist rech unspektakulär: Hello from Facelets.

Ein Blick auf die URL zeigt, dass hier eine Anfrage an den lokalen Server gestellt wurde, und zwar im Verzeichnis JSFTutorial. Erinnern Sie sich? Dies ist genau der Context Path, den Sie im Assistenten angegeben haben, bzw. der aus dem Projektnamen übernommen wurde.

Ein Blick auf den Sourcecode der Seite (bei Firefox mittels {Ctrl}{u} erreichbar), zeigt normales XHTML:

<?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">
    <head>
        <title>Facelet Title</title>
    </head>
    <body>
      Hello from Facelets
    </body>
</html>

Vergleichen Sie dies mit dem Sourcecode, so fällt auf, dass die Angabe des JSF-HTML Namespaces verschwunden sind, ebenso wie die “h:” Präfixe. Hier hat also bereits der Server im Hintergrund gewerkelt: Die spezifischen Tags wurden analysiert und ersetzt. Im vorliegenden Fall nur durch einfachen HTML Code. In späteren Projekten auch dynamisch durch die Ausgabe der Applikationen. Es wird also spannend.

An diesere Stelle sollte sich eigentlich eine Erläuterung dessen anschließen, was denn da serverseitig so alles passiert. Doch vor einem solch “trockenem” Thema gibt es im nächsten Abschnitt erst einmal eine kleine interaktive Applikation. Sie haben doch sicherlich auch erst einmal erlebt, wie ein Auto fährt, bevor Sie selbst zur Fahrschule gingen, oder?