AVID Übung 2 Tag Libraries, JavaServer Faces Andreas I. Schmied (schmied@inf...) Abteilung Verteilte Systeme Universität Ulm SS2005 Wiederholung Und nun. . . 1 Wiederholung Übung 1 Lösungen zur Übung 1 Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 2 / 77 Wiederholung Übung 1 Wiederholung – Übung 1 XML (mit Java) DOM vs. Push/Pull-Stream diverse APIs Servlets CGI für Java“ ” doPost/doGet(Request req, Response res) res.setContentType(”text/html”) res.getWriter().print(”<html>...”) Scopes: Application, Session, Request, ... JavaServer Pages invertierte Servlets Markup + Tag-Libraries + Scriptlets + Expression Language Zugriff auf Java Beans ohne Java“ ” Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 4 / 77 Wiederholung Lösungen zur Übung 1 Wiederholung – Lösungen zur Übung 1 Selber ausprobieren und ggf. nachfragen! Eclipse-Projekte zum Download auf der Vorlesungsseite Servlet-Variante JSP-Variante ... Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 5 / 77 Tag Libraries Und nun. . . 2 Tag Libraries JSTL Custom Tags Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 6 / 77 Tag Libraries JSTL JSTL – JSP Standard Tag Library standardisierte“ Tags ” Interoperabilität Rollentrennung, Programmierung ohne Java“ ” XML-Manipulation, DB, I18N, Conditionals, Flusskontrolle Komponenten Core – http://java.sun.com/jsp/jstl/core XML – http://java.sun.com/jsp/jstl/xml I18N – http://java.sun.com/jsp/jstl/fmt SQL – http://java.sun.com/jsp/jstl/sql Functions – http://.../jsp/jstl/functions Tag Files, Functions, ... hier nur in aller Kürze! Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 7 / 77 Tag Libraries JSTL JSTL – Benutzung Deklaration als xmlns:prefix oder: <%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %> Interaktion mit Tag-Daten 1 2 <c:set var=”bookId” value=”${param.Add}”/> <jsp:useBean id=”bookId” type=”java.lang.String” /> 3 4 <% cart.add(bookId); %> 5 6 7 8 9 <sql:query var=”books” dataSource=”${applicationScope.DB}”> select ∗ from PUBLIC.books where id = ? <sql:param value=”${bookId}” /> </sql:query> 1 – Export als EL-Variable bookID 2 – Deklaration als Bean bookID für Scriptlet 4 – Verwendung des Beans im Scriptlet 8 – Verwendung der EL-Variable Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 9 / 77 Tag Libraries JSTL JSTL – Beispiel: Core Variablen setzen/löschen 1 2 <c:set var=”pass” scope=”session” value=”${param.PwdField}”/> <c:remove var=”pass” scope=”session”/> Flusskontrolle 1 <c:if test=”...”>... 2 3 4 5 <c:choose> <c:when test=”...”>... <c:otherwise> ... 6 7 <c:forEach var=”item” items=”${sessionScope.cart.items}”>... Import (zwischengepuffert) 1 2 <c:import url=”/books.xml” var=”xml”> <c:param ...> 3 4 5 <c:redirect url=”...”> <c:param ...> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 11 / 77 Tag Libraries Custom Tags Tag Libraries – Custom Tags Implementierung, z.B.: 1 2 3 4 5 public ATagImpl extends SimpleTagSupport { ... public void doTag() throws JspException, IOException { getJspContext().getOut().write(”AVID−SS05”); } } zusätzlich Parameter, Variablen, Nested-Tags, ... Descriptor (TLD) 1 2 3 4 5 6 7 8 9 ... <tag> <name>atag</name> <tag-class>infvs.avid.tags.ATagImpl</tag−class> <body-content>scriptless</body−content> ... <attribute> <name>test</name> ... </attribute> ... </tag> weitaus komplexere Konstrukte möglich... Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 13 / 77 JavaServer Faces Und nun. . . 3 JavaServer Faces Motivation Beispiel Tomcat-Anpassung More on JSF... Literatur Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 14 / 77 JavaServer Faces Motivation Motivation – Bisherige Technologien Servlets Scope-Daten manuell (Session, ...) Parameter-Verarbeitung manuell Ausgabe manuell JSP Ausgabe vorgefertigt Expression Language für Scope/Parameter-Daten JSP + Tag Libraries Tags für Komponenten, Verhalten, Flusskontrolle Java-Entkopplung durch Tags + Beans Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 15 / 77 JavaServer Faces Motivation Motivation – Verbesserungen? hochwertige GUI im Browser unabhängig von HTML, beliebiges Markup Datenmodell/Verhalten von Präsentation trennen Abstraktion von Formularfeldern, Links, ... Daten in Objektmodell in Server Automatischer Abgleich mit Formularfeldern Validierung der Eingaben, ggf. Fehlermeldung Abstraktion von Scope/Parameter-Daten Reagieren auf Browser-Events (Clicks, Eingaben, Selektion) mit Listeners/Bean-Methoden im Server Choreographie zwischen den Seiten Navigationspfade deklarativ konfigurieren Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 16 / 77 JavaServer Faces Motivation Motivation – Die Idee Daten/Verhalten Server-seitig in Beans GUI-Komponenten Server-seitig als Objektbaum Abbildung auf bel. Markup mit RenderKits dafür JSF-Tags in JSP eingebettet JSF prinzipiell unabhängig von JSP! Verknüpfung zwischen Komponenten und Beans generisches Faces-Servlet für alle JSF-Requests bildet Aktion/Parameter auf Bean-Methode/-Properties ab deklarative Bean-Konfig. und Navigation zwischen Seiten Konzept: modifizierte Model-View-Controller Architektur (MVC) Wichtig: Objektmodell getrennt testbar! Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 17 / 77 JavaServer Faces Motivation Motivation – Konzeptskizze (vereinfacht) Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 19 / 77 JavaServer Faces Beispiel Beispiel – Hinweis das Beispiel ist stark gekürzt keine optimale/effiziente Implementierung nur einfacher Demonstrator schöpft bei weitem nicht alle JSF-Features aus siehe Literaturliste Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 20 / 77 JavaServer Faces Beispiel Beispiel – Aufbau einfacher Kalender (Pseudocode) 1 2 3 4 Calendar { Users { int id; String name, password; } Entries { int ownerId; String text; } } Web Application Deployment Descriptor: web.xml Application Configuration Resource File: faces-config.xml JavaServer Pages index.jsp – <jsp:forward page =”faces/login.jsp”/> login.jsp – Auswahl eines Benutzers + Passworteingabe calendar.jsp – Anzeigen und Hinzufügen von Einträgen Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 22 / 77 JavaServer Faces Beispiel Beispiel – web.xml generisches Faces Servlet 1 2 3 <?xml version=”1.0” encoding=”UTF−8”?> <web−app version=”2.4” xmlns=”http://java.sun.com/xml/ns/j2ee” ...> 4 5 6 7 8 9 <servlet> <servlet−name>FacesServlet</servlet−name> <servlet−class>javax.faces.webapp.FacesServlet</servlet−class> <load−on−startup>1</load−on−startup> </servlet> 10 11 12 13 14 <servlet−mapping> <servlet−name>FacesServlet</servlet−name> <url−pattern>/faces/*</url−pattern> </servlet−mapping> 15 16 </web−app> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 24 / 77 JavaServer Faces Beispiel Beispiel – faces-config.xml Rahmenaufbau 1 <?xml version=”1.0” encoding=”iso−8859−1” ?> 2 3 4 5 <!DOCTYPE faces−config PUBLIC ”−//Sun ..., Inc.//DTD JavaServer Faces Config 1.0//EN” ”http://java.sun.com/dtd/web−facesconfig 1 0.dtd”> 6 7 8 9 10 <faces-config> ... <managed-bean> ... <navigation-rule> ... 11 12 </faces−config> Bean-Konfiguration (s.u.) Navigationspfade (s.u.) Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 26 / 77 JavaServer Faces Beispiel Beispiel – Beans Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 28 / 77 JavaServer Faces Beispiel Beispiel – Bean-Implementierung auf allen Folien sind Getter/Setter gekürzt UserBean 1 2 3 4 public class UserBean { private int id; private String name, pass; } CalendarBean 1 2 3 public class CalendarBean { private List entries = new ArrayList(); } EntryBean 1 2 3 4 public class EntryBean { int owner; // −> UserBean.id String text; } Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 30 / 77 JavaServer Faces Beispiel Beispiel – Bean-Konfiguration in faces-config.xml Instanziierung, Benennung, Verknüpfung deklarativ! 1 2 3 4 5 6 7 8 9 10 11 <managed-bean> <managed-bean-name>userMap</managed−bean−name> <managed-bean-class>java.util.HashMap</managed−bean−class> <managed-bean-scope>application</managed−bean−scope> <map-entries> <key-class>int</key−class> <value-class>infvs.cal.UserBean</value−class> ... <map-entry> <key>#{user2.id}</key> <value>#{user2}</value> ... 12 13 14 15 16 17 18 19 20 21 <managed-bean> <managed-bean-name>user2</managed−bean−name> <managed−bean−class>infvs.cal.UserBean</managed−bean−class> <managed−bean−scope>application</managed−bean−scope> ... <managed-property> <property-name>name</property−name> <value>schmied</value> ... Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 32 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Screenshot Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 34 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Quellcode (1) 1 <html> <head><title>Login</title></head> <body> 2 3 4 <% @ taglib uri=”http://java.sun.com/jsf/html” prefix=”h” % > <% @ taglib uri=”http://java.sun.com/jsf/core” prefix=”f” % > 5 6 7 <f:view> <h:form id=”login”> 8 9 <h1>Login</h1> 10 11 <h:panelGrid columns=”3”> ... s.u. ... </h:panelGrid> 12 13 14 15 16 17 <h:commandButton id=”submit” value=”Login” action=”#{LoginController.login}” /> </h:form> </f:view> </body> </html> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 36 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Quellcode (1) Tag Libraries Core und HTML Tags mit HTML-Code durchmischt (kritisch, siehe Literatur!) alle JSF-Tags in <f:view> gekapselt Formular <h:form> <h:panelGrid> für dreispaltiges Layout (s.u.) Button löst Bean-Methode LoginController.login() aus Expression Language in JSF: #{...} in nächster JSF-Version an JSP-EL angepasst Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 38 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Quellcode (2) 1 <h:panelGrid columns=”3”> 2 3 4 5 6 7 <h:outputLabel value=”User” for=”user” /> <h:selectOneMenu id=”user” value=”#{LoginController.id}” ...> <f:selectItems value=”#{itemsUsers}”/> </h:selectOneMenu> <h:message for=”user”/> 8 9 10 11 <h:outputLabel value=”Password” for=”pass” /> <h:inputSecret id=”pass” binding=”#{LoginController.uiPass}” ... /> <h:message for=”pass” /> 12 13 </h:panelGrid> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 40 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Quellcode (2) <h:panelGrid> gruppiert automatisch pro columns“ Elemente ” <h:outputLabel> ist an Element gebunden <h:message> stellt Fehlermeldung dar Bindung an Objektmodell: 2 Varianten <h:inputSecret> ist an Server-seitige GUI-Komponente gebunden für konfigurierbare Komponenten (Ausblenden, Deaktivieren, ...) <h:selectOneMenu> setzt Auswahl direkt in Bean-Property für einfache Wertzuweisung <h:selectOneMenu> bindet List-Objekt mit Elementen Elemente sind vom Typ javax.faces.model.SelectItem! Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 42 / 77 JavaServer Faces Beispiel Beispiel – faces-config.xml – itemsUsers 1 2 3 4 5 6 7 8 9 10 <managed−bean> <managed−bean−name>itemsUsers</managed−bean−name> <managed−bean−class>java.util.ArrayList</managed−bean−class> <managed−bean−scope>application</managed−bean−scope> <list-entries> <value-class>javax.faces.model.SelectItem</value−class> <value>#{itemUser1}</value> <value>#{itemUser2}</value> </list−entries> </managed−bean> 11 12 13 14 15 16 17 18 19 20 21 22 <managed−bean> <managed−bean−name>itemUser1</managed−bean−name> <managed−bean−class>javax.faces.model.SelectItem</managed−bean−class> <managed−bean−scope>application</managed−bean−scope> <managed−property> <property−name>label</property−name> <value>#{user1.name}</value> </managed−property> <managed−property> <property−name>value</property−name> <value>#{user1.id}</value> </managed−property> </managed−bean> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 44 / 77 JavaServer Faces Beispiel Beispiel – login.jsp – Screenshot Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 46 / 77 JavaServer Faces Beispiel Beispiel – LoginController 1 2 3 import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.component.UIInput; 4 5 public class LoginController { 6 private java.util.HashMap userMap; // = ? private int id; private UIInput uiPass = new UIInput(); 7 8 9 10 public String login() { UserBean user = (UserBean) userMap.get(getId()); String pass = (String) uiPass.getValue(); boolean ok = user.getPass().equals(pass); if (!ok) { FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(uiPass.getClientId(context), new FacesMessage(”Wrong Password”)); } return ok ? ”success” : null; } 11 12 13 14 15 16 17 18 19 20 21 22 } Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 48 / 77 JavaServer Faces Beispiel Beispiel – LoginController.login() Initialisierung von userMap? extern, deklarativ in faces-config.xml wichtiges Prinzip: Inversion of Control / Dependency Injection liest gerade gesetzte ID + dazugehöriges UserBean gibt success“ als positiven Outcome“ zurück ” ” Outcome dient als Trigger für deklarative Navigation (s.u.) gibt null“ als negativen Outcome zurück ” aktuellen View unverändert darstellen <h:message> für Komponente pass“ setzen ” Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 50 / 77 JavaServer Faces Beispiel Beispiel – faces-config.xml – LoginController Session Scope Property userMap wird gesetzt 1 2 3 4 5 6 7 8 9 10 <managed−bean> <managed−bean−name>LoginController</managed−bean−name> <managed−bean−class>infvs.cal.LoginController</...> <managed−bean−scope>session</managed−bean−scope> <managed−property> <property−name>userMap</property−name> <value>#{userMap}</value> </managed−property> </managed−bean> ... Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 52 / 77 JavaServer Faces Beispiel Beispiel – Navigation Outcome statisch oder als Rückgabe von Action-Handler deklarativ in faces-config.xml 1 2 3 4 5 6 7 <navigation-rule> <from-view-id>/login.jsp</from−view−id> <navigation-case> <from-outcome>success</from−outcome> <to-view-id>/calendar.jsp</to−view−id> </navigation−case> </navigation−rule> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 54 / 77 JavaServer Faces Beispiel Beispiel – calendar.jsp – Screenshot Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 56 / 77 JavaServer Faces Beispiel Beispiel – calendar.jsp – Quellcode (1) 1 <html> <head><title>Calendar</title></head> <body> 2 3 4 <% @ taglib uri=”http://java.sun.com/jsf/html” prefix=”h” % > <% @ taglib uri=”http://java.sun.com/jsf/core” prefix=”f” % > 5 6 7 <f:view> <h:form id=”calendar”> 8 9 <h1>Calendar</h1> 10 11 12 13 14 <h:dataTable id=”entries” value=”#{calendar.entries}” var=”entry”> <h:column> ... s.u. ... </h:column> <h:column> ... s.u. ... </h:column> </h:dataTable> 15 16 17 <h:commandButton id=”add” value=”Add Entry” action=”#{CalendarController.add}” /> 18 19 </h:form> </f:view> </body> </html> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 58 / 77 JavaServer Faces Beispiel Beispiel – calendar.jsp – Quellcode (2) 1 <h:dataTable id=”entries” value=”#{calendar.entries}” var=”entry”> 2 3 4 <h:column> <f:facet name=”header”> <h:outputText value=”Owner” /> </f:facet> 5 6 7 8 <h:commandLink action=””> <h:outputText id=”owner” value=”#{userMap[entry.owner].name}”/> </h:commandLink> 9 10 </h:column> 11 12 13 <h:column> <f:facet name=”header”> <h:outputText value=”Text”/> </f:facet> 14 15 <h:inputText size=”40” value=”#{entry.text}”/> 16 17 </h:column> 18 19 </h:dataTable> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 60 / 77 JavaServer Faces Beispiel Beispiel – calendar.jsp – Quellcode (2) <h:dataTable> mit Daten aus value-Attribut #{calendar.entries} ist java.util.List Iteration über var-Attribut entry jeweils an ein EntryBean gebunden pro <h:column> ein Kopfelement über <f:facet> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 62 / 77 JavaServer Faces Beispiel Beispiel – CalendarController 1 import javax.faces.context.FacesContext; 2 3 public class CalendarController { 4 private LoginController loginData; // = ? 5 6 public String add() { FacesContext context = FacesContext.getCurrentInstance(); 7 8 9 CalendarBean cal = (CalendarBean) context.getExternalContext() .getApplicationMap().get(”calendar”); 10 11 12 cal.getEntries().add(new EntryBean(loginData.getId(), ”<new>”)); 13 14 return ”success”; 15 } 16 17 } Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 64 / 77 JavaServer Faces Beispiel Beispiel – faces-config.xml – CalendarController Session Scope Property loginData wird gesetzt 1 <managed−bean> 2 3 4 5 <managed−bean−name>CalendarController</managed−bean−name> <managed−bean−class>infvs.cal.CalendarController</managed−bean−class> <managed−bean−scope>session</managed−bean−scope> 6 7 8 9 10 <managed−property> <property−name>loginData</property−name> <value>#{LoginController}</value> </managed−property> 11 12 </managed−bean> Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 66 / 77 JavaServer Faces Tomcat-Anpassung JavaServer Faces – Tomcat-Anpassung JSF- und Tool-Bibliotheken installieren in $Tomcat/shared/lib kopieren in WEB-INF/lib der WAR-Datei (zu groß?!) packen Entweder aus Sun’s JSF-Beispielen/Download commons-beanutils.jar commons-collections.jar commons-digester.jar commons-logging.jar jsf-api.jar jsf-impl.jar oder aus Sun’s J2EE Application Server appserv-jstl.jar appserv-rt.jar jsf-api.jar jsf-impl.jar Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 68 / 77 JavaServer Faces More on JSF... More on JSF... – Design über CSS-Attribute/-Classes viele UI-Komponenten (Communities!) Converters, Events/Listeners per Java-Script auch Client-seitige Event-Handler Validators 1 2 3 <h:inputSecret id=”pass” binding=”#{LoginController.uiPass}”> <f:validateLength minimum=”4” maximum=”10” /> </h:inputSecret> per Java-Script auch Validierung im Browser möglich Mischen von Faces mit Non-Faces, Apache-Frameworks, ... Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 70 / 77 JavaServer Faces More on JSF... More on JSF... – Gesamter Life Cycle Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 72 / 77 JavaServer Faces Literatur JavaServer Faces – Literatur www.ibm.com/developerworks/library/j-jsf1 bisher drei von vier Artikeln (j-jsf1...3) www.servlets.com/soapbox/problems-jsp.html www.servlets.com/soapbox/problems-jsp-reaction. html howardlewisship.com/blog/2004/06/ more-on-tapestry-and-jsf.html www.onjava.com/lpt/a/4919 java.sun.com/j2ee/javaserverfaces J2EE-Tutorial Kap. 17-21 Community: jsfcentral.com www.oracle.com/technology/tech/java/jsf.html Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 73 / 77 Ausblick Und nun. . . 4 Ausblick Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 74 / 77 Ausblick Ausblick Das war erst der Anfang... Konzeptfragen mehrere Sessions pro Browser Performance von Servlet-Filtern vernünftige URLs Nebeneffekte von Navigations-Buttons/Reload im Browser Authenication/Authorisation, Security, SSL/TLS JSP/JSF-Customising, Tag Libraries Internationalisierung (i18n, l10n) div. Apache-Frameworks rund um Servlets, XML-Processing Dependency Injection/Inversion of Control (IoC) Directory Services, Persistenz, Transaktionen, Lastverteilung Folgende Übungen Enterprise JavaBeans Integration mit Servlet/JSP/JSF Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 75 / 77 Aufgabe Und nun. . . 5 Aufgabe Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 76 / 77 Aufgabe Aufgabe Je nach Geschmack und Zeit... Custom Tags zum Zugriff auf Kalenderdaten Login/Calendar-Beispiel nachbauen JSF-Tutorial, Artikel lesen Andreas I. Schmied (schmied@inf...) AVID Übung 2 SS2005 77 / 77