Erste Schritte mit JavaServer Faces und MyEclipse Allgemeines

Transcrição

Erste Schritte mit JavaServer Faces und MyEclipse Allgemeines
Erste Schritte mit JavaServer Faces und MyEclipse
Dieses Tutorial soll den Einstieg in das noch recht neue Framework, JavaServer Faces (JSF),
erleichtern. Es wird Schritt für Schritt eine Beispiel-Anwendung (eine Bibliothek) erstellt, die den
Umgang mit verschiedenen Elementen des Frameworks aufzeigt.
Die Beispielanwendung soll folgende Funktionalität bieten:
•
Ausgabe einer Bücherübersicht (Liste aller Bücher)
•
Hinzufügen, bearbeiten und löschen von Büchern
Allgemeines
Autor:
Sascha Wolski
Sebastian Hennebrüder
http://www.laliluna.de/tutorials.html Tutorials für Struts, EJB, xdoclet und eclipse.
Datum:
December, 21 2004
Source code:
Die Sourcen enthalten keine Projektdateien oder irgendwelche Libraries. Erstelle ein neues
Projekt, wie im Tutorial erklärt, füge die Libraries hinzu, gleichfalls wie im Tutorial erklärt und
kopiere die Sourcen in Dein neues Projekt.
http://www.laliluna.de/assets/tutorials/first-java-server-faces-tutorial.zip
PDF Version des Tutorials:
http://www.laliluna.de/assets/tutorials/first-java-server-faces-tutorial-de.pdf
Development Tools
Eclipse 3.x
MyEclipse plugin 3.8
(Ein kostengünstige, leistungsfähige Erweiterung für die Entwicklung von Web Anwendungen und
EJB Applikationen, Testversion gibt es bei MyEclipse.)
Database
PostgreSQL 8.0 Beta
Application Server
Jboss 3.2.5
You may use Tomcat here if you like.
Erstellen eines JavaServer Faces Projektes
Erstelle ein neues Web-Projekt mit File > New > Project.
Gib deinem Projekt einen geeigneten Namen und füge die JSTL Bibliotheken hinzu.
Füge dem Projekt die JavaServer Faces Unterstützung hinzu. Rechte Maustaste auf das Projekt,
MyEclipse > Add JSF Capabilities.
Die Klasse Book
Lege ein neues Package de.laliluna.tutorial.library an und erstelle eine neue Klasse
Book.
Öffne die Klasse und füge folgende private Eigenschaften hinzu:
•
id
•
author
•
title
•
available
Generiere für jede Eigenschaft der Klasse eine Getter- und Setter-Methode.
Desweiteren soll ein Konstruktor hinzugefügt werden, der es erlaubt die Eigenschaften der
Instanzvariable beim Initialisieren zu setzen.
Der folgende Quelltext zeigt die Klasse Book.
public class Book implements Serializable {
//
------------------ Properties
private long id;
private String author;
private String title;
private boolean available;
--------------------------------
//
------------------ Constructors -------------------------------public Book(){}
public Book(long id, String author, String title, boolean available){
this.id = id;
this.author = author;
this.title = title;
this.available = available;
}
//
------------------ Getter and setter methods ---------------------
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
Füge noch einen Getter- und Setter für die Klasse hinzu.
/**
* Set the properties
* @param book
*/
public void setBook(Book book){
this.setId(book.getId());
this.setAuthor(book.getAuthor());
this.setTitle(book.getTitle());
this.setAvailable(book.isAvailable());
}
/**
* @return book object
*/
public Book getBook(){
}
return new Book(this.getId(),
this.getAuthor(),
this.getTitle(),
this.isAvailable());
Die Datenbank Klasse
Wir verzichten in diesem Tutorial auf die Anbindung einer Datenbank und stellen einige Testdaten
mit einer Klasse bereit. Lade dir das Beispiel-Projekt zu diesem Tutorial herunter und kopiere die
Klasse SimulateDB.java aus dem Verzeichnis src/de/laliluna/tutorial/library/ in
das Package de.laliluna.tutorial.library.
Die BookList Klasse
Erstelle eine weitere Klasse BookList im Package de.laliluna.library. Diese Klasse
beinhaltet eine Eigenschaft books,welche ein Liste aller Bücher darstellt. Erstelle für die
Eigenschaft books eine Getter- und Setter-Methode und ändere die Getter-Methode wie folgt ab.
public class BookList {
// ------------------------- Properties --------------------------Collection books;
// ------------------------- Getter and Setter -------------------/**
* @return collection of books
*/
public Collection getBooks(){
SimulateDB simulateDB = new SimulateDB();
/* Holt sich die Session auf dem Externen Context
*/
Map session = FacesContext.getCurrentInstance().getExternalContext
().getSessionMap();
/* Lies alle Bücher auf der simulierten Datenbank aus
*/
books = simulateDB.getAllBooks(session);
}
}
return books;
/**
* @param books The books to set.
*/
public void setBooks(Collection books) {
this.books = books;
}
Dein Package Explorer sollte wie folgt aussehen.
Action Listener Methoden
Damit der Benutzer später ein Buch hinzufügen, bearbeiten oder löschen kann, muss noch die
entsprechende Funktionalität abgebildet werden. Diese werden in sogenannte Action Listener
Methoden / Klassen implementiert. Eine Action Listener Methode / Klasse wird beim Eintreten
eines Ereignisses (zBsp.:Benutzer klickt auf einen Link) aufgerufen und abgearbeitet.
Öffne die Klasse Book und erstelle vier Methoden für die folgende Funktionalität abbilden.
•
Initialisieren eines Buches
•
Auslesen eines Buches zum Bearbeiten
•
Speichern eines Buches
•
Löschen eines Buches
Initialisieren eines Buches
/**
* Initialisiert die Eigenschaften der Klasse mit null
* @param event
*/
public void initBook(ActionEvent event){{
}
/*
* Eigenschaften initialisieren
*/
this.setBook(new Book());
Auslesen eines Buches zum Bearbeiten
/**
* Liest das zu bearbeitende Buch aus
* und weisst es dem Bean zu
*
* @param event
*/
public void selectBook(ActionEvent event){
SimulateDB simulateDB = new SimulateDB();
/*
* Holt sich die Session auf dem Externen Context
*/
Map session = FacesContext.getCurrentInstance().getExternalContext().
getSessionMap();
/*
* Such die UIParameter Komponente anhand des Ausdrucks
*/
UIParameter component = (UIParameter) event.getComponent().findComponent
("editId");
/*
* Parse den Value der UIParameter Komponente
*/
long id = Long.parseLong(component.getValue().toString());
}
/*
* Ließ das Buch anhand der id aus und setze die lokalen Eigenschaften
*/
this.setBook(simulateDB.loadBookById(id, session));
Speichern eines Buches
/**
* Legt oder aktualisiert ein Buch in der simulierten Datenbank
* Wenn die id des Buches nicht gesetzt ist wird das Buch
* angelegt, ansonsten wird das Buch aktualsiert.
*
* @param event
*/
public void saveBook(ActionEvent event){
SimulateDB simulateDB = new SimulateDB();
/*
* Holt sich die Session auf dem Externen Context
*/
Map session = FacesContext.getCurrentInstance().getExternalContext().
getSessionMap();
}
/*
* Fügt hinzu oder aktualisiert das Buch in der
* simulierten Datenbank
*/
simulateDB.saveToDB(this.getBook(), session);
Löschen eines Buches
/**
* Löscht ein Buch aus der simulierten Datenbank
*
* @param event
*/
public void deleteBook(ActionEvent event){
SimulateDB simulateDB = new SimulateDB();
/*
* Holt sich die Session auf dem Externen Context
*/
Map session = FacesContext.getCurrentInstance().getExternalContext().
getSessionMap();
/*
* Such die UIParameter Komponente anhand des Ausdrucks
*/
UIParameter component = (UIParameter) event.getComponent().findComponent
("deleteId");
/*
* Parse den Value der UIParameter Komponente
*/
long id = Long.parseLong(component.getValue().toString());
}
/*
* Lösche das Buch anhand der seiner id
*/
simulateDB.deleteBookById(id, session);
Die Datei faces-config.xml
Die faces-config.xml ist die zentrale Konfigurationsdatei für JavaServer Faces. Wir definieren hier
den Ablauf unserer Anwendung (auf welche Aktion wird welche Seite verarbeitet), die vom JSF zu
verwaltenden Bean Klassen und einiges mehr.
Der Ablauf der Bibliotheken-Anwendung sieht wie folgt aus.
Wir definieren dafür die sogenannten Navigationsregeln.
Öffne die Datei faces-config.xml und füge folge Konfiguration hinzu.
<faces-config>
<!-- Navigation rules -->
<navigation-rule>
<description>List of books</description>
<from-view-id>/listBooks.jsp</from-view-id>
<navigation-case>
<from-outcome>editBook</from-outcome>
<to-view-id>/editBook.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>Add or edit a book</description>
<from-view-id>/editBook.jsp</from-view-id>
<navigation-case>
<from-outcome>listBooks</from-outcome>
<to-view-id>/listBooks.jsp</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
<navigation-rule>
Definiert eine Navigationregel
<from-view-id>/listBooks.jsp</from-view-id>
Gibt die JSP Datei an, für die diese Navigationregel zutrifft.
<navigation-case>
Definiert einen Navigationsfall
<from-outcome>editBook</from-outcome>
Definiert einen Namen für den Navigationsfall
<to-view-id>/listBooks.jsp</to-view-id>
Verweist auf die angegebene JSP Datei
<redirect/>
Wenn dieser Tag gestetzt wird, werden die Parameter die sich im Request befinen nicht mit
übertragen.
Damit wir in den JSP Dateien auf unsere Bean Klassen zugreifen können, müssen wir diese in der
faces-config.xml registrieren.
Füge folgenden Quelltext hinzu.
<!-- Managed beans -->
<managed-bean>
<description>
Book bean
</description>
<managed-bean-name>bookBean</managed-bean-name>
<managed-bean-class>de.laliluna.tutorial.library.Book</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>
BookList Bean
</description>
<managed-bean-name>bookListBean</managed-bean-name>
<managed-bean-class>de.laliluna.tutorial.library.BookList</managed-beanclass>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
Definiert eine zu verwaltendes Bean.
<managed-bean-name>bookBean</managed-bean-name>
Vergibt einen Namen für das zu verwaltende Bean. Dieser Name wird in der JSP Datei genutzt.
<managed-bean-class>de.laliluna.tutorial.library.Book</managed-bean-class>
Gibt die Klasse die das Bean darstellt an.
<managed-bean-scope>request</managed-bean-scope>
Definiert in welchem Scope das zu verwaltende Bean gespeichert werden soll.
Erstellen der JSP Dateien
Wir erstellen im ersten Schritt eine JSP Datei index.jsp, die den Benutzer auf die
Bücherübersicht weiterleitet.
index.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<jsp:forward page="/listBooks.faces" />
</body>
</html>
Im zweiten Schritt erstellen wir die Bücherübersicht.
listBooks.jsp
<%@ page language="java" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>List of books</title>
</head>
<body>
<f:view>
<h:form id="bookList">
<h:dataTable id="books"
value="#{bookListBean.books}"
var="book"
border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Author"/>
</f:facet>
<h:outputText value="#{book.author}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:outputText value="#{book.title}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Available"/>
</f:facet>
<h:selectBooleanCheckbox disabled="true"
value="#{book.available}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink id="Edit"
action="editBook"
actionListener="#{bookBean.selectBook}">
<h:outputText value="Edit" />
<f:param id="editId"
name="id"
value="#{book.id}" />
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Delete"/>
</f:facet>
<h:commandLink id="Delete"
action="listBooks"
actionListener="#{bookBean.deleteBook}">
<h:outputText value="Delete" />
<f:param id="deleteId"
name="id"
value="#{book.id}" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:commandLink id="Add"
action="editBook"
actionListener="#{bookBean.initBook}">
<h:outputText value="Add a book" />
</h:commandLink>
</h:form>
</f:view>
</body>
</html>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
Mit der Direktive taglib werden die JSF eigenen Tag Bibliotheken geladen
<f:view>
Definiert einen View-Komonente, alle weiteren JSF Tags müssen sich innerhalb dieses Tags
befinden.
<h:form id="bookList">
Definiert eine HTML Form
<h:dataTable id="books" value="#{bookListBean.books}" var="book" border="1">
Definiert eine HTML Table. Der Tag wird genutz um über Listen zu laufen und die Daten dieser
Liste auszugeben, vergleichbar mit einer for Schleife. Mit dem Parameter value weist man eine
Liste von Daten zu, in unserem Falle die Liste der vorhanden Bücher unserer Bibliothek. Mit dem
Parameter var definieren wir eine Variable mit der wir innerhalb des Tags (Loops) auf das
aktuelle Element (ein Buch) der Liste zugreifen können.
<h:column>
<f:facet name="header">
<h:outputText value="Author"/>
</f:facet>
<h:outputText value="#{book.author}" />
</h:column>
Definiert eine Spalte mit einem Spaltenkopf.
<f:facet name="header"> Definiert den Spaltenkopf
<h:outputText value="Author"/> gibt den Wert Author im Spaltenkopf aus.
<h:outputText value="#{book.author}" /> bezieht sich auf die Eigenschaft author
unserer Book Klasse.
<h:commandLink id="Edit"
action="editBook"
actionListener="#{bookBean.selectBook}">
Definiert einen HTML Link, der beim Aufruf das Formular abschickt. Der Parameter action gibt
an welcher Navigationsfall nach dem Abschicken abgearbeitet werden soll. In diesem Fall greift
der Navigationsfall editBook, den wir zuvor in der faces-config.xml angegeben haben. Mit
dem Parameter actionListener weisen wir dem Link die Action Listener Methode
selectBook unseres Book Beans zu. Nach dem Abschicken des Formulars wird die Listener
Methode aufgerufen und abgearbeitet.
Die letzte JSP Datei, beinhaltet ein Formular zum Anlegen und Bearbeiten eines Buches.
editBook.jsp
<%@ page language="java" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Add / Edit a book</title>
</head>
<body>
<f:view>
<h:form>
<h:inputHidden id="id" value="#{bookBean.id}"/>
<h:panelGrid columns="2" border="1">
<h:outputText value="Author:" />
<h:inputText id="author"
value="#{bookBean.author}">
</h:inputText>
<h:outputText value="Title:" />
<h:inputText id="title"
value="#{bookBean.title}">
</h:inputText>
<h:outputText value="Available:" />
<h:selectBooleanCheckbox id="available"
value="#{bookBean.available}" />
</h:panelGrid>
<h:commandButton value="Save"
action="listBooks"
actionListener="#{bookBean.saveBook}" />
</h:form>
</f:view>
</body>
</html>
<h:inputHidden id="id" value="#{bookBean.id}"/>
Definiert ein HTML Hidden Element mit dem Wert der Eigenschaft id unserer Book Klasse.
Value bezieht sich hier auf das Managed Bean bookBean, welches in der faces-config.xml
angegeben ist.
<h:panelGrid columns="2" border="1">
Definiert eine HTML Table mit zwei Spalten, wobei column die Anzahl der Spalten angibt.
<h:inputText id="author" value="#{bookBean.author}">
Definiert ein HTML Textfeld mit dem Wert der Eigenschaft author unserer Book Klasse.
<h:commandButton value="Save"
action="listBooks"
actionListener="#{bookBean.saveBook}" />
Erstellt einen HTML Submit Button mit dem Value Save und der Action listBooks. Die Action
Listener Methode saveBook wird nach dem Abschicken des Formulars aufgerufen.
Testen der Anwendung
Starte den Jboss und Deploye das Projekt als Packaged Archive
Rufe danach das Projekt auf http://localhost:8080/LibraryWeb/

Documentos relacionados