5. JavaServerFaces(JSF) -...

37
Komponentenbasierte Software- Entwicklung Prof. Dr. Stephan Kleuker 207 5. JavaServer Faces (JSF) • Grundlagen • Nutzung von JSF-Annotationen • Validierung von Eingaben • Ausgabe von Fehlermeldungen • Auswahl darzustellender Elemente • typische elementare Software-Architektur • JSF + JPA • Visualisierungskomponenten

Transcript of 5. JavaServerFaces(JSF) -...

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

207

5. JavaServer Faces (JSF)

• Grundlagen

• Nutzung von JSF-Annotationen

• Validierung von Eingaben

• Ausgabe von Fehlermeldungen

• Auswahl darzustellender Elemente

• typische elementare Software-Architektur

• JSF + JPA

• Visualisierungskomponenten

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

208

Literatur

• M. Marinschek, M. Kurz, G. Müllan, JavaServer Faces 2.0, dpunkt, Heidelberg, 2010 (im Wesentlich auch: http://tutorials.irian.at/jsf/semistatic/introduction.html)

• K. Ka Iok Tong, Beginning JSF 2 APIs and JBoss Seam, Apress, Berkeley, USA, 2009

• Standard: Sun, JSR 314: JavaServer Faces 2.0, http://www.jcp.org/en/jsr/detail?id=314

• Sun, JEE6 Tutorial, http://java.sun.com/javaee/6/docs/tutorial/doc

• Bücher fixieren teilweise auf Eclipse und JBoss; nicht notwendig, funktioniert fast alles mit Netbeans und Glassfish / Apache

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

209

Generelle Ziele

verschiedene Ziele

• Software, die Web als zusätzlichen Nutzen hat (z. B. Web-Präsenz, Kataloge, Bestellmöglichkeiten)

• verteilte Softwaresysteme, die Netz als Komponentenverbindung nutzen (z. B. B2B)

• Arbeitsplatzsoftware, die auch das Web nutzt (nahtlose Integration, Web ist „unsichtbar“)

• letztes Ziel gewinnt immer mehr Bedeutung für andere Ziele

• Aber: Nicht immer ist Web-fähige Software gewünscht!

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

210

Technische Herausforderungen (1/2)

auf welchem Rechner läuft welche Software

• zentraler Server oder peer-to-peer

• Client-Server, wer ist thin, wer ist fat

Browser-fähig oder standalone

• welcher Browser, welche Sicherheitseinstellungen, welche Plugins, welches HTML

• Wie bekommt Kunde Software zum Laufen, wie funktionieren Updates

• darf man, muss man offline arbeiten können

• Usability

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

211

Technische Herausforderungen (2/2)

Sicherheit

• wie Daten sicher verschicken, wem gehört Internet, wer muss zuhören dürfen

Performance und Stabilität

• schnelle Antworten auch bei Last

• saubere, reproduzierbare Transaktionen

• was passiert bei Netzausfall

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

212

Typische Entwicklungsplattformen (Ausschnitt)

.Net / Microsoft• ASP.Net (Active Server Pages, gute Abstraktion, zunächst zu

wenig Web-Server (IIS))• Silverlight (Browser-PlugIn) für RIA, mittlerweile auch lokal• Oberflächen basierend auf WPF (Windows Presentation

Forum, vektorbasiert, anfänglich zu langsam)Java• Servlets, JSP, JSF [später genauer], angegeben mit

steigenden Abstraktionsgrad ser weit verbreitet• verschiedene neue Frameworks (z. B. Apache Wicket)• GWT (Google Widget Toolset), SW einmal in Java schreiben,

dann individuell für Browser in Javascript übersetzen• JavaFX , eigene Sprache nutzt im Browser JRE• Meinung: Silverlight und JavaFX gegenüber Flash(-

Nachfolger) immer im Nachteil

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

213

Konzept eines Seitenaufrufs

• HTML (Hypertext Markup Language)

– Auszeichnungssprache mit festgelegten tags zum Aufbau der Ausgabe

• Ebene 3/4 typisch TCP/IP, Session Ebene 5: HHTP, Darstellungsebene 6: HTML, Programmebene 7: JVM

ClientClientClientClient

WebWebWebWeb----ServerServerServerServer

ServerServerServerServer

HTTPHTTPHTTPHTTP----RequestRequestRequestRequest

HTTPHTTPHTTPHTTP----ResponseResponseResponseResponsemitmitmitmitHTMLHTMLHTMLHTML----Datei im Body Datei im Body Datei im Body Datei im Body

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

214

HTTP-Ablauf

• Client: Request

– get, post, head, put, ... URL HTTP1.x

– Header Info: Accept, Cookie, ...

– Body: Post-Parameter

• Server: Response

– Statusmeldung: HTTP1.x 200 OK, oder 404 Error

– Header Info: Content-type, set-cookie, ...

– Body: Dokument

• Verbindungsabbau

• Protokoll ist zustandslos/gedächtnislos; Client wird bei erneutem Request ohne Trick nicht als Bekannter erkannt

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

215

Web-Server mit Container nutzen

• Servlet: Wortkreation aus den Begriffen „Server“und „Applet“, (serverseitiges Applet)

• Web-Server leitet HTTP-Request an Servlet weiter

• Servlet kann Antwort (HTML-Code) berechnen

• Servlet kann Anfrage-Informationen und Serverumgebung nutzen

• Servlet kann mit anderen Servlets kommunizieren

Container

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

216

Motivation für JSF

• Die Widerverwendbarkeit von Servlets ist gering

• Innerhalb jeder JSP bzw. jedes Servlets müssen ähnliche Schritte ausgeführt werden

• Nur ein Teil der Applikationslogik kann in Tag-Bibliotheken gekapselt werden

• Workflow ist in der Applikationslogik versteckt, dadurch schwer nachvollzierbar

• ab JSF 2.0 sehr flexible Gestaltungsmöglichkeiten, u. a. AJAX-Einbettung

• Hinweis: wir betrachten nur Grundkonzepte (-> mehr evtl. Semesteraufgabe)

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

217

Web-Server mit JSF- (und EJB-) Unterstützung

• Beispiele:

– Apache + Tomcat

– BEA WebLogic Server

– IBM WebSphere (Apache Geronimo)

– JBoss

– Oracle WebLogic

– Sun Glassfish Enterprise Server (Glassfish)

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

218

Konzeptübersicht

Input-Komponente beschrieben in

XHTML...

Web-Seite in XHTML

Output-Komponente beschrieben in

XHTML...

Web-Seite in XHTML

Modell

Java-Programmim Container

im Server

eventeventeventevent

leitet aufleitet aufleitet aufleitet aufFolgeseiteFolgeseiteFolgeseiteFolgeseite

liestliestliestliest

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

219

XHTML

• Idee: HTML nicht XML-konform und zu viele Freiheiten

• XHTML in fast allen Elementen wie HTML

• XHTML basierend auf XML-Schema leichter zu verarbeiten

• Unterschiede zu HTML (Ausschnitt)

– Tags und Attribute müssen klein geschrieben werden

– Attributwerte immer in Anführungsstrichen boarder="7"boarder="7"boarder="7"boarder="7"

– korrekte XML-Syntax: <<<<brbrbrbr/>/>/>/> nicht <<<<brbrbrbr>>>>

– generell saubere Terminierung <<<<inputinputinputinput ... />... />... />... />

• XHTML2 wegen HTML5 zurückgestellt http://www.w3.org/2009/06/xhtml-faq.html

• Standard: http://www.w3.org/TR/xhtml1/

• Literatur: U. Ogbuji, XHTML step-by-step, http://www.ibm.com/developerworks/edu/x-dw-x-xhtml-i.html

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

220

Web-GUI-Komponenten

• JSF bietet alle klassischen GUI-Komponenten zur Darstellung und Bearbeitung an

• Grundidee: Komponenten schicken bei Veränderungen Events

• Nutzung von MVC2

• Komponenten als XHTML eingebettet

<<<<h:inputTexth:inputTexth:inputTexth:inputText id="id="id="id="imnameimnameimnameimname" value="#{" value="#{" value="#{" value="#{modul.namemodul.namemodul.namemodul.name}}}}““““required="true"/>required="true"/>required="true"/>required="true"/>

<<<<h:outputTexth:outputTexth:outputTexth:outputText idididid====""""omnameomnameomnameomname" " " " value="#{modul.namevalue="#{modul.namevalue="#{modul.namevalue="#{modul.name}"/>}"/>}"/>}"/>

• Kontakt zum Java-Programm über Methodenaufrufe (lesend und aufrufend, z. B. modul.setNamemodul.setNamemodul.setNamemodul.setName(...), (...), (...), (...), modul.getNamemodul.getNamemodul.getNamemodul.getName()()()()

• große Komponenten können aus kleineren komponiert werden

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

221

Nulltes JSF-Beispiel (1/11)

• Aufgabe: Modul (Name + Nummer) eingeben und auf zweiter Seite wieder ausgeben

• Beispiel zeigt:

– Konzept der XHTML-Nutzung

– erste JSF-Befehle

– Seitenmanövrierung durch JSF

• 0. Beispiel zeigt nicht:

– ordentliche Softwarearchitektur (Controller und Model trennen)

– Validierungsmöglichkeiten für Eingaben

– Layoutgestaltung

– viele coole Dinge

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

222

<?<?<?<?xmlxmlxmlxml version='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 Transitional//ENTransitional//ENTransitional//ENTransitional//EN" " " "

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><<<<htmlhtmlhtmlhtml xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/html">">">"><<<<h:headh:headh:headh:head>>>><<<<title>Moduleingabe</titletitle>Moduleingabe</titletitle>Moduleingabe</titletitle>Moduleingabe</title>>>>

</</</</h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnameid="mnameid="mnameid="mname" " " " value="#{modul.namevalue="#{modul.namevalue="#{modul.namevalue="#{modul.name}" }" }" }"

required="true"/><brrequired="true"/><brrequired="true"/><brrequired="true"/><br/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnrid="mnrid="mnrid="mnr" " " " value="#{modul.nrvalue="#{modul.nrvalue="#{modul.nrvalue="#{modul.nr}" }" }" }"

required="true"/><brrequired="true"/><brrequired="true"/><brrequired="true"/><br/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Abschickenvalue="Abschickenvalue="Abschickenvalue="Abschicken" " " "

action="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmen}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Nulltes JSF-Beispiel (2/11) - Start index.xhtml

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

223

Nulltes JSF-Beispiel (3/11) - Analyse der Startseite

• Einbinden der JSF-Bibliotheken<<<<htmlhtmlhtmlhtml xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/html""""xmlns:fxmlns:fxmlns:fxmlns:f ="="="="http://java.sun.com/jsf/corehttp://java.sun.com/jsf/corehttp://java.sun.com/jsf/corehttp://java.sun.com/jsf/core" >" >" >" >

• Nutzung von Standard XHTML (vereinfacht, da so als Standardnamensraum gesetzt)

• enge Verwandtschaft HTML zu XHTML (<h:form>)

• für value="#{modul.namevalue="#{modul.namevalue="#{modul.namevalue="#{modul.name}" }" }" }" offene Fragen:

– was ist modul? ( -> Managed Bean)

– warum #? (Trennung von ausführbaren Elementen)

– was passiert bei modul.name? (set/get abhängig von in/out)

• Ausblick: action="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmen}"}"}"}", echtes Event-Handling (Methodenaufruf)

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

224

Nulltes JSF-Beispiel (4/11) - Ausgabe ausgabe.xhtml

<?<?<?<?xmlxmlxmlxml version='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 Transitional//ENTransitional//ENTransitional//ENTransitional//EN" " " "

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><<<<htmlhtmlhtmlhtml xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/htmlxmlns:h="http://java.sun.com/jsf/html">">">"><<<<h:headh:headh:headh:head>>>><<<<title>Modulausgabe</titletitle>Modulausgabe</titletitle>Modulausgabe</titletitle>Modulausgabe</title>>>>

</</</</h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname: "/>: "/>: "/>: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnameid="mnameid="mnameid="mname" " " " value="#{modul.namevalue="#{modul.namevalue="#{modul.namevalue="#{modul.name}"/> <}"/> <}"/> <}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer: "/>: "/>: "/>: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnrid="mnrid="mnrid="mnr" " " " value="#{modul.nr}"/><brvalue="#{modul.nr}"/><brvalue="#{modul.nr}"/><brvalue="#{modul.nr}"/><br/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Zurvalue="Zurvalue="Zurvalue="Zur Eingabe" Eingabe" Eingabe" Eingabe"

action="#{modul.eingebenaction="#{modul.eingebenaction="#{modul.eingebenaction="#{modul.eingeben}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

225

Nulltes JSF-Beispiel (5/11) - Managed Bean [1/3]

packagepackagepackagepackage entitiesentitiesentitiesentities;;;;

importimportimportimport java.io.Serializablejava.io.Serializablejava.io.Serializablejava.io.Serializable;;;;importimportimportimport javax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBean;;;;importimportimportimport javax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScoped;;;;

@@@@ManagedBean(name="modulManagedBean(name="modulManagedBean(name="modulManagedBean(name="modul")")")")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;private private private private intintintint nrnrnrnr;;;;private String private String private String private String namenamenamename;;;;

publicpublicpublicpublic Modul(){}Modul(){}Modul(){}Modul(){}

publicpublicpublicpublic Modul(intModul(intModul(intModul(int nrnrnrnr, String , String , String , String namenamenamename) {) {) {) {this.nrthis.nrthis.nrthis.nr = = = = nrnrnrnr;;;;this.namethis.namethis.namethis.name = = = = namenamenamename;;;;

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

226

Nulltes JSF-Beispiel (6/11) - Managed Bean [2/3]

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen(){(){(){(){returnreturnreturnreturn "./"./"./"./ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml";";";";

}}}}

publicpublicpublicpublic String eingeben(){String eingeben(){String eingeben(){String eingeben(){returnreturnreturnreturn "./"./"./"./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml";";";";

}}}}

publicpublicpublicpublic String String String String getNamegetNamegetNamegetName() {() {() {() {returnreturnreturnreturn namenamenamename;;;;

}}}}

publicpublicpublicpublic voidvoidvoidvoid setName(StringsetName(StringsetName(StringsetName(String namenamenamename) {) {) {) {this.namethis.namethis.namethis.name = = = = namenamenamename;;;;

}}}}

publicpublicpublicpublic intintintint getNrgetNrgetNrgetNr() {() {() {() {returnreturnreturnreturn nrnrnrnr;;;;

}}}}

publicpublicpublicpublic voidvoidvoidvoid setNr(intsetNr(intsetNr(intsetNr(int nrnrnrnr) {) {) {) {this.nrthis.nrthis.nrthis.nr = = = = nrnrnrnr;;;;

}}}}

//Man//Man//Man//Manöööövrierenvrierenvrierenvrieren

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

227

Nulltes JSF-Beispiel (7/11) - Managed Bean [3/3]

@@@@OverrideOverrideOverrideOverridepublicpublicpublicpublic booleanbooleanbooleanboolean equals(Objectequals(Objectequals(Objectequals(Object objectobjectobjectobject) {) {) {) {ifififif ((((object==nullobject==nullobject==nullobject==null || !(|| !(|| !(|| !(objectobjectobjectobject instanceofinstanceofinstanceofinstanceof Modul)) Modul)) Modul)) Modul)) returnreturnreturnreturn falsefalsefalsefalse;;;;

Modul Modul Modul Modul otherotherotherother = (Modul) = (Modul) = (Modul) = (Modul) objectobjectobjectobject;;;;ifififif ((((this.nrthis.nrthis.nrthis.nr != != != != other.nrother.nrother.nrother.nr || !|| !|| !|| !this.name.equals(other.namethis.name.equals(other.namethis.name.equals(other.namethis.name.equals(other.name)) )) )) )) returnreturnreturnreturn falsefalsefalsefalse;;;;

returnreturnreturnreturn truetruetruetrue;;;;}}}}

@@@@OverrideOverrideOverrideOverride // generieren lassen// generieren lassen// generieren lassen// generieren lassenpublicpublicpublicpublic intintintint hashCodehashCodehashCodehashCode() {() {() {() {intintintint hashhashhashhash = 5;= 5;= 5;= 5;hashhashhashhash = 47 * = 47 * = 47 * = 47 * hashhashhashhash + + + + this.nrthis.nrthis.nrthis.nr;;;;hashhashhashhash = 47 * = 47 * = 47 * = 47 * hashhashhashhash

+ (+ (+ (+ (this.namethis.namethis.namethis.name != null ? != null ? != null ? != null ? this.name.hashCodethis.name.hashCodethis.name.hashCodethis.name.hashCode() : 0);() : 0);() : 0);() : 0);returnreturnreturnreturn hashhashhashhash;;;;

}}}}

@@@@OverrideOverrideOverrideOverridepublicpublicpublicpublic String String String String toStringtoStringtoStringtoString() {() {() {() {returnreturnreturnreturn name+"("+nrname+"("+nrname+"("+nrname+"("+nr+")";}+")";}+")";}+")";}

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

228

Nulltes JSF-Beispiel (8/11) - web.xml [1/2]• Konfigurationsdatei für Servlets (hier benötigt)• sun-web.xml ist Glassfish-spezifische Konfiguratonsdatei<?<?<?<?xmlxmlxmlxml version="1.0" encoding="UTFversion="1.0" encoding="UTFversion="1.0" encoding="UTFversion="1.0" encoding="UTF----8"?>8"?>8"?>8"?><<<<webwebwebweb----appappappapp version="3.0" version="3.0" version="3.0" version="3.0"

xmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaee" " " " xmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/web----app_3_0.xsd">app_3_0.xsd">app_3_0.xsd">app_3_0.xsd">

<<<<contextcontextcontextcontext----paramparamparamparam>>>><<<<paramparamparamparam----name>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</param----namenamenamename>>>><<<<paramparamparamparam----value>Development</paramvalue>Development</paramvalue>Development</paramvalue>Development</param----valuevaluevaluevalue>>>>

</</</</contextcontextcontextcontext----paramparamparamparam>>>><<<<servletservletservletservlet>>>><<<<servletservletservletservlet----name>Facesname>Facesname>Facesname>Faces Servlet</servletServlet</servletServlet</servletServlet</servlet----namenamenamename>>>><<<<servletservletservletservlet----class>javax.faces.webapp.FacesServletclass>javax.faces.webapp.FacesServletclass>javax.faces.webapp.FacesServletclass>javax.faces.webapp.FacesServlet</</</</servletservletservletservlet----classclassclassclass>>>><load<load<load<load----onononon----startup>1</loadstartup>1</loadstartup>1</loadstartup>1</load----onononon----startup>startup>startup>startup>

</</</</servletservletservletservlet>>>>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

229

Nulltes JSF-Beispiel (9/11) - web.xml [2/2]

<<<<servletservletservletservlet----mappingmappingmappingmapping>>>><<<<servletservletservletservlet----name>Facesname>Facesname>Facesname>Faces Servlet</servletServlet</servletServlet</servletServlet</servlet----namenamenamename>>>><<<<urlurlurlurl----pattern>/faces/*</urlpattern>/faces/*</urlpattern>/faces/*</urlpattern>/faces/*</url----patternpatternpatternpattern>>>>

</</</</servletservletservletservlet----mappingmappingmappingmapping>>>><<<<sessionsessionsessionsession----configconfigconfigconfig>>>><<<<sessionsessionsessionsession----timeouttimeouttimeouttimeout>>>>30303030

</</</</sessionsessionsessionsession----timeouttimeouttimeouttimeout>>>></</</</sessionsessionsessionsession----configconfigconfigconfig>>>><<<<welcomewelcomewelcomewelcome----filefilefilefile----listlistlistlist>>>><<<<welcomewelcomewelcomewelcome----file>faces/index.xhtml</welcomefile>faces/index.xhtml</welcomefile>faces/index.xhtml</welcomefile>faces/index.xhtml</welcome----filefilefilefile>>>>

</</</</welcomewelcomewelcomewelcome----filefilefilefile----listlistlistlist>>>></</</</webwebwebweb----appappappapp>>>>

in sun-web.xml steht u. a.<context<context<context<context----root>/JSFSpielerei2</contextroot>/JSFSpielerei2</contextroot>/JSFSpielerei2</contextroot>/JSFSpielerei2</context----root>root>root>root>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

230

Nulltes JSF-Beispiel (10/11) - Projektstruktur

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

231

Nulltes JSF-Beispiel (11/11) - Ergebnis

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

232

Basisprinzip der Applikationssteuerung

• Im Controller: Auftruf einer Methode ohne Parameter vom Rückgabetyp String<<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Abschickenvalue="Abschickenvalue="Abschickenvalue="Abschicken" " " "

action="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmenaction="#{modul.uebernehmen}"/>}"/>}"/>}"/>

• Im Modell:publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen(){(){(){(){

returnreturnreturnreturn "./"./"./"./ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml";";";";}}}}

• Methode kann natürlich abhängig von Variablen unterschiedliche Seiten liefern

• Beachten: Navigation kann in den Tiefen des Codes verschwinden ( -> Konstanten nutzen, Architektur)

• Hinweis: wir werden noch Varianten kennenlernen

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

233

Lebensdauer von Informationen (scope)

• Anmerkung: Obwohl es verlockend ist, viele Informationen in Session oder Application zu legen, ist dies wg Performance verboten (wird gespeichert, evtl. passiviert, hat wilde Referenzen, Zugriff muss ggfls. synchronisiert werden)

RequestRequestRequestRequest

SessionSessionSessionSession

ApplicationApplicationApplicationApplication

nur für einenAufruf (auch fürWeiterleitung)

für eineNutzer-Sitzung

solangeaktuellesDeploymentläuft

NoneNoneNoneNone

nur aktuelleSeite

Zeit

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

234

Scope-Beispiel (1/5) - Bean-Klasse

//@//@//@//@ManagedBean(nameManagedBean(nameManagedBean(nameManagedBean(name = "= "= "= "modulmodulmodulmodul")")")")//@//@//@//@RequestScopedRequestScopedRequestScopedRequestScoped Modul als einfache KlasseModul als einfache KlasseModul als einfache KlasseModul als einfache Klassepublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable { ...// wie vorher{ ...// wie vorher{ ...// wie vorher{ ...// wie vorher

@@@@ManagedBean(nameManagedBean(nameManagedBean(nameManagedBean(name = "= "= "= "modulnmodulnmodulnmoduln")")")")

@@@@NoneScopedNoneScopedNoneScopedNoneScopedpublic class public class public class public class ModulNoneModulNoneModulNoneModulNone extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBean(nameManagedBean(nameManagedBean(nameManagedBean(name = "= "= "= "modulrmodulrmodulrmodulr")")")")

@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublic class public class public class public class ModulRequestModulRequestModulRequestModulRequest extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBean(nameManagedBean(nameManagedBean(nameManagedBean(name = "= "= "= "modulsmodulsmodulsmoduls")")")")

@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublic class public class public class public class ModulSessionModulSessionModulSessionModulSession extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBean(nameManagedBean(nameManagedBean(nameManagedBean(name = "= "= "= "modulamodulamodulamodula")")")")

@@@@ApplicationScopedApplicationScopedApplicationScopedApplicationScopedpublicpublicpublicpublic classclassclassclass ModulApplicationModulApplicationModulApplicationModulApplication extendsextendsextendsextends Modul{}Modul{}Modul{}Modul{}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

235

Scope-Beispiel (2/5) - Ausschnitt index.xhtml<<<<h:formh:formh:formh:form>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid columns="3" >columns="3" >columns="3" >columns="3" ><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel for="mnamenfor="mnamenfor="mnamenfor="mnamen" " " " value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnamenid="mnamenid="mnamenid="mnamen" " " " value="#{moduln.namevalue="#{moduln.namevalue="#{moduln.namevalue="#{moduln.name}"/>}"/>}"/>}"/><<<<h:messageh:messageh:messageh:message for="mnamenfor="mnamenfor="mnamenfor="mnamen" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel for="mnrnfor="mnrnfor="mnrnfor="mnrn" " " " value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnrnid="mnrnid="mnrnid="mnrn" " " " value="#{moduln.nrvalue="#{moduln.nrvalue="#{moduln.nrvalue="#{moduln.nr}"/> }"/> }"/> }"/> <<<<h:messageh:messageh:messageh:message for="mnrnfor="mnrnfor="mnrnfor="mnrn" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel for="mnamerfor="mnamerfor="mnamerfor="mnamer" " " " value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnamerid="mnamerid="mnamerid="mnamer" " " " value="#{modulr.namevalue="#{modulr.namevalue="#{modulr.namevalue="#{modulr.name}"/>}"/>}"/>}"/><<<<h:messageh:messageh:messageh:message for="mnamerfor="mnamerfor="mnamerfor="mnamer" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel for="mnrrfor="mnrrfor="mnrrfor="mnrr" " " " value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer "/>"/>"/>"/><<<<h:inputTexth:inputTexth:inputTexth:inputText id="mnrrid="mnrrid="mnrrid="mnrr" " " " value="#{modulr.nrvalue="#{modulr.nrvalue="#{modulr.nrvalue="#{modulr.nr}"/> }"/> }"/> }"/> <<<<h:messageh:messageh:messageh:message for="mnrrfor="mnrrfor="mnrrfor="mnrr" />" />" />" /><!<!<!<!-------- auch auch auch auch modulsmodulsmodulsmoduls und und und und modulamodulamodulamodula -------->>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Abschickenvalue="Abschickenvalue="Abschickenvalue="Abschicken""""

action="#{modulr.uebernehmenaction="#{modulr.uebernehmenaction="#{modulr.uebernehmenaction="#{modulr.uebernehmen}"/>}"/>}"/>}"/></</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

236

Scope-Beispiel (3/5) - Ausschnitt ausgabe.xhtml

<<<<h:formh:formh:formh:form>>>><<<<h:messagesh:messagesh:messagesh:messages globalOnly="trueglobalOnly="trueglobalOnly="trueglobalOnly="true"/>"/>"/>"/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname n: "/>n: "/>n: "/>n: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnamenid="mnamenid="mnamenid="mnamen" " " " value="#{moduln.namevalue="#{moduln.namevalue="#{moduln.namevalue="#{moduln.name}"/> <}"/> <}"/> <}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer n: "/>n: "/>n: "/>n: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnrnid="mnrnid="mnrnid="mnrn" " " " value="#{moduln.nr}"/><brvalue="#{moduln.nr}"/><brvalue="#{moduln.nr}"/><brvalue="#{moduln.nr}"/><br/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnamevalue="Modulnamevalue="Modulnamevalue="Modulname r: "/>r: "/>r: "/>r: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnamerid="mnamerid="mnamerid="mnamer" " " " value="#{modulr.namevalue="#{modulr.namevalue="#{modulr.namevalue="#{modulr.name}"/> <}"/> <}"/> <}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="Modulnummervalue="Modulnummervalue="Modulnummervalue="Modulnummer r: "/>r: "/>r: "/>r: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText id="mnrrid="mnrrid="mnrrid="mnrr" " " " value="#{modulr.nr}"/><brvalue="#{modulr.nr}"/><brvalue="#{modulr.nr}"/><brvalue="#{modulr.nr}"/><br/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Zurvalue="Zurvalue="Zurvalue="Zur Eingabe" Eingabe" Eingabe" Eingabe"

action="#{modulr.eingeben}"/><braction="#{modulr.eingeben}"/><braction="#{modulr.eingeben}"/><braction="#{modulr.eingeben}"/><br/>/>/>/><!<!<!<!-------- auch auch auch auch modulsmodulsmodulsmoduls und und und und modulamodulamodulamodula -------->>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton value="Ausgabevalue="Ausgabevalue="Ausgabevalue="Ausgabe wiederholen" wiederholen" wiederholen" wiederholen"

action="#{modulr.uebernehmenaction="#{modulr.uebernehmenaction="#{modulr.uebernehmenaction="#{modulr.uebernehmen}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

237

Scope-Beispiel (4/5) - Ein Nutzer, zwei Klicks

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

238

Scope-Beispiel (5/5) - Zwei NutzerN

utz

er

1N

utz

er

2

Zeit

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

239

Manövrieren vor JSF 2.0

• Grundidee: Automat mit Seiten als Knoten (Zustände), Übergang findet durch String-Konstanten statt

• String-Konstanten sind Ergebnisse von (Action-) Methoden (oder stehen direkt in action="EINGEBENaction="EINGEBENaction="EINGEBENaction="EINGEBEN"""")

index.xhtml

ausgabe.xhtml

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

240

Manövrieren vor JSF 2.0 - faces-config.xml 1/2<?<?<?<?xmlxmlxmlxml version='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTFversion='1.0' encoding='UTF----8'?>8'?>8'?>8'?><<<<facesfacesfacesfaces----configconfigconfigconfig version="1.2" version="1.2" version="1.2" version="1.2"

xmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaeexmlns="http://java.sun.com/xml/ns/javaee" " " " xmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeexsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/web----facesconfig_1_2.xsd">facesconfig_1_2.xsd">facesconfig_1_2.xsd">facesconfig_1_2.xsd">

<<<<navigationnavigationnavigationnavigation----rulerulerulerule>>>><<<<fromfromfromfrom----viewviewviewview----id>/index.xhtml</fromid>/index.xhtml</fromid>/index.xhtml</fromid>/index.xhtml</from----viewviewviewview----idididid>>>><<<<navigationnavigationnavigationnavigation----casecasecasecase>>>><<<<fromfromfromfrom----outcome>ANZEIGEN</fromoutcome>ANZEIGEN</fromoutcome>ANZEIGEN</fromoutcome>ANZEIGEN</from----outcomeoutcomeoutcomeoutcome>>>><<<<totototo----viewviewviewview----id>/ausgabe.xhtml</toid>/ausgabe.xhtml</toid>/ausgabe.xhtml</toid>/ausgabe.xhtml</to----viewviewviewview----idididid>>>>

</</</</navigationnavigationnavigationnavigation----casecasecasecase>>>></</</</navigationnavigationnavigationnavigation----rulerulerulerule>>>><<<<navigationnavigationnavigationnavigation----rulerulerulerule>>>><<<<fromfromfromfrom----viewviewviewview----id>/ausgabe.xhtml</fromid>/ausgabe.xhtml</fromid>/ausgabe.xhtml</fromid>/ausgabe.xhtml</from----viewviewviewview----idididid>>>><<<<navigationnavigationnavigationnavigation----casecasecasecase>>>><<<<fromfromfromfrom----outcome>EINGEBEN</fromoutcome>EINGEBEN</fromoutcome>EINGEBEN</fromoutcome>EINGEBEN</from----outcomeoutcomeoutcomeoutcome>>>><<<<totototo----viewviewviewview----idididid>/ >/ >/ >/ index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml </</</</totototo----viewviewviewview----idididid>>>>

</</</</navigationnavigationnavigationnavigation----casecasecasecase>>>></</</</navigationnavigationnavigationnavigation----rulerulerulerule>>>>

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

241

Manövrieren vor JSF 2.0 - Managed Bean

// statt durch Annotationen k// statt durch Annotationen k// statt durch Annotationen k// statt durch Annotationen köööönnen nnen nnen nnen BeansBeansBeansBeans auch in auch in auch in auch in facesfacesfacesfaces----// // // // config.xmlconfig.xmlconfig.xmlconfig.xml angelegt werdenangelegt werdenangelegt werdenangelegt werdenpublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;private private private private intintintint nrnrnrnr;;;;private String private String private String private String namenamenamename;;;;// fehlt: // fehlt: // fehlt: // fehlt: getgetgetget---- und und und und setsetsetset----MethodenMethodenMethodenMethoden ffffüüüür Exemplarvariablenr Exemplarvariablenr Exemplarvariablenr Exemplarvariablenpublicpublicpublicpublic Modul(){}Modul(){}Modul(){}Modul(){}

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen(){ //Action(){ //Action(){ //Action(){ //Action----MethodeMethodeMethodeMethode// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen mööööglichglichglichglichreturnreturnreturnreturn "ANZEIGEN";"ANZEIGEN";"ANZEIGEN";"ANZEIGEN";

}}}}

publicpublicpublicpublic String eingeben(){String eingeben(){String eingeben(){String eingeben(){// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen m// Zugriff auf Exemplarvariablen mööööglichglichglichglichreturnreturnreturnreturn "EINGEBEN";"EINGEBEN";"EINGEBEN";"EINGEBEN";

}}}}............

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

242

Manövrieren vor JSF 2.0 - faces-config.xml 2/2

<<<<managedmanagedmanagedmanaged----beanbeanbeanbean>>>><<<<managedmanagedmanagedmanaged----beanbeanbeanbean----name>modul</managedname>modul</managedname>modul</managedname>modul</managed----beanbeanbeanbean----namenamenamename>>>><<<<managedmanagedmanagedmanaged----beanbeanbeanbean----class>entities.Modul</managedclass>entities.Modul</managedclass>entities.Modul</managedclass>entities.Modul</managed----beanbeanbeanbean----classclassclassclass>>>><<<<managedmanagedmanagedmanaged----beanbeanbeanbean----scope>request</managedscope>request</managedscope>request</managedscope>request</managed----beanbeanbeanbean----scopescopescopescope>>>>

</</</</managedmanagedmanagedmanaged----beanbeanbeanbean>>>></</</</facesfacesfacesfaces----configconfigconfigconfig>>>>

Vorteil der klassischen Navigation:

• Es gibt zentrale Stelle, an der es einen Überblick über mögliche Abläufe gibt

Nachteile:

• JSF 2.0 bietet flexiblere Ablaufsteuerung

• XML ist schwer nachvollziehbar

• Konfigurationsdatei facesfacesfacesfaces----config.xmlconfig.xmlconfig.xmlconfig.xml bleibt trotzdem wichtig

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

243

Erinnerung: Konstanten in Programmen

• schlecht returnreturnreturnreturn "ANZEIGEN";"ANZEIGEN";"ANZEIGEN";"ANZEIGEN";

• besser: Konstanten getrennt deklarierenpublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable{{{{private final private final private final private final staticstaticstaticstatic stringstringstringstring ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";............returnreturnreturnreturn ANZEIGEN;ANZEIGEN;ANZEIGEN;ANZEIGEN;

• Alternativ: Klasse mit Konstantenpackagepackagepackagepackage konstanten;konstanten;konstanten;konstanten;publicpublicpublicpublic classclassclassclass Navigation{Navigation{Navigation{Navigation{publicpublicpublicpublic final final final final staticstaticstaticstatic stringstringstringstring ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";ANZEIGEN = "ANZEIGEN";............returnreturnreturnreturn konstanten.Navigation.ANZEIGENkonstanten.Navigation.ANZEIGENkonstanten.Navigation.ANZEIGENkonstanten.Navigation.ANZEIGEN;;;;

– Entwicklungsumgebungen erlauben dann einfache Suche und Änderung (Refactoring)