First steps tutorial using struts and eclipse Erstellen eines Struts

Transcription

First steps tutorial using struts and eclipse Erstellen eines Struts
First steps tutorial using struts and eclipse
In diesem Tutorial möchte ich erste Schritte im Umgang mit dem Web Framework Apache Struts
und der Entwicklungsumgebung Eclipse beschreiben. Als Beispiel - Anwendung erstellen wir eine
Verwaltung von Büchern.
Allgemeines
Autor:
Sascha Wolski
http://www.laliluna.de/tutorial.html – Tutorials für Struts, EJB, xdoclet und eclipse.
Datum:
November, 2st 2004
Development Tools
Eclipse 3.x
MyEclipse plugin 3.8
(A cheap and quite powerful Extension to Eclipse to develop Web Applications and EJB (J2EE)
Applications. I think that there is a test version availalable at MyEclipse.)
Source code:
http://www.laliluna.de/tutorial/first-struts/first_steps_with_struts.zip
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.
PDF Version des Tutorials
http://www.laliluna.de/assets/tutorials/first_steps_with_struts_de.pdf
Erstellen eines Struts Projektes
Erstelle ein neues Projekt mit File > New > Project oder per Shortcut mit Strg + n.
Im Dialog New wählen wir unter J2EE das Web Project aus.
Gibt deinem Projekt einen netten Namen.
Dein Package Explorer sollte nach dem Anlegen wie folgt aussehen.
Das Projekt ist bis jetzt nur ein schlichtes J2EE Web Projekt, es fehlt uns also noch die
Unterstützung für Struts. Klicke mit der rechten Maustaste auf das Projekt und füge mit
Add Struts Capabilityies die Funktionalität hinzu.
Ändere die Einstellungen Base package for new classes und
Default application resource
Erstellen einer Default und Willkommen Seite
Dann wollen wir mal unsere Default Seite erstellen. Dazu klicken wir mit der rechten Maustaste
(ja schon wieder) auf den WebRoot Ordner und wählen danach JSP unter New aus.
Im Dialog vergeben wir den Namen index.jsp und wählen bei Template to use, Standard
JSP using Struts 1.1 aus. Damit wird bei der Erstellung der JSP Datei die Schabole für
Struts 1.1 genutzt.
Die Datei index.jsp befindet sich jetzt im WebRoot Verzeichnis des Projektes.
Wenn wir die Datei öffnen, befinden sich im oberen Teil die sogenannten Struts Tag Libraries
(Bibliotheken). Diese werden benötigt um die Struts eigenen Tags zu verwenden.
In unserem Falle benötigen wir nur die Logic Tag Library.
Folgende Zeile fügen wir unter den Include der Logic Tag Library.
<logic:forward name="welcome" />
Diese Zeile veranlasst Struts nach einem Forward (Weiterleitung) mit dem Namen welcome zu
suchen. Findet die Applikation dieses Forward nicht, führt dies zu einem Fehler. Im nächsten
Abschnitt wird kurz erläutert was ein Action Forward ist.
Erstelle eine zweite JSP Datei index.jsp im Verzeichnis /WebRoot/jsp.
Ändere hier den Body der Datei.
<body>
Welcome!
<br>
<html:link action="bookList">Show the booklist</html:link>
</body>
Global Action Forwards und Action Mappings
Was ist ein Action Forward?
Wie der englische Name schon sagt ist ein Forward eine Weiterleitung. Es gibt in Struts zwei
Typen von Forwards, zum Einen ein globales und ein lokales Action Forward.
Das globale Action Forward kann aus jeder Action Klasse und JSP Datei aufgerufen werden.
Das lokale Action Forward wiederum nur aus der zugehörigen Action Klasse.
Was ist ein Action Mapping?
Das Action Mapping von Struts ist das Herzstück für die Interaktion mit dem Benutzer. Es wird
festgelegt welche URL auf welche Action Klasse verweist und welche JSP Dateien von dieser
Action Klasse aufgerufen werden kann.
Das Diagramm zeigt, wie sich der Applikationsserver beim Aufruf der index.jsp oder eines
unbekannten Action Mappings verhält
Erstelle im ersten Schritt das Action Mapping. Dazu öffnen wir die Konfigurationsdatei strutsconfig.xml im Verzeichnis WebRoot/WEB-INF. Damit wir nicht alles von Hand eintragen
müssen, bietet MyEcplise einen Wizard an. Dieser befindet sich im Outline Feld von MyEcplise.
Wir klicken mit der rechten Maustaste auf action-mapping und wählen den Menüpunkt New
Action.
Trage im Dialog New Action bei Use Case default ein und wähle bei Action Type Forward
aus. Bei Forward Path tragen wir unsere Willkommen Seite /jsp/index.jsp ein.
Im zweiten Schritt erstellen wir nun das Global Action Forward. Dazu gehen wir wieder zurück in
das Outline Fenster von MyEclipse und klicken mit der rechten Maustaste auf Global Forward.
Wähle den Forward Scope "Global Forward" aus. Wir verwenden den Namen, den wir in
unserer Default Seite vergeben haben. Das Global Forward verweist auf unser ActionMapping.
Folgendes sollte im Editorfenster von MyEclipse zu sehen sein.
<global-forwards >
<forward name="welcome" path="/default.do" redirect="true" />
</global-forwards>
<action-mappings >
<action forward="/jsp/index.jsp" path="/default" />
</action-mappings>
Damit ein Aufruf eines nicht existierenden Action Mapping zu keinem Fehler führt (zBsp.: /xyz.do),
müssen wir unserem "default" Action Mapping noch einen Parameter unknow="true" anhängen.
<action-mappings >
<action forward="/jsp/index.jsp" path="/default" unknown="true"/>
</action-mappings>
Anwendungsfall Buchliste
Eine Struts Action tut immer irgendwas und speichert das Ergebnis in einem Actionform. Die
Daten des ActionForms können dann für die Anzeige in einem JSP verwendet werden.
Unser Action wird Bücher aus einer Datenbank laden und in eine ActionForm speichern. Das JSP
wird diese Daten dann nacher anzeigen.
Erstellen einer Objekt Klasse „Book“
Erstelle im Package de.laliluna.tutorial.library eine neue Klasse Book.
Die Klasse Book soll ein Buch darstellen mit den Eigenschaften Id, Autor, Titel, Verfügbarkeit.
Wir legen dafür vier Variablen an.
Um auf die privaten Variablen zugreifen zu können, erstellen wir für jede einen Getter und Setter.
Rechte Maustaste in der Klasse, Source > Generate Getters and Setters.
Wähle Select All und Insertion point Last method.
Füge noch zwei Konstruktoren der Klasse hinzu, damit wir beim Initialiseren der Klassen die
Eigenschaften setzen können.
// Contructor
public Book(){}
// Contructor to initial the properties
public Book(long id, String author, String title, boolean available) {
this.id = id;
this.author = author;
this.title = title;
this.available = available;
}
Damit ist unser Klasse Book fertig.
Erstellen eines Form Beans, Action Form und JSP
Öffne die struts-config.xml und klicke mit der rechten Mausetaste auf Form Bean im
Outline Fenster.
Use Case ist bookList, Superclass org.apache.struts.ActionForm und bei Methods nur
public void reset.. Unter JSP vergeben wir einen Namen für die JSP Datei.
Der Package Explorer sieht wie folgt aus:
Bearbeiten des Quelltextes der Action Form Klasse
Öffne die Datei BookListForm.java und füge den folgenden Quelltext hinzu.
public class BookListForm extends ActionForm {
private Collection books;
/* lalinuna.de 02.11.2004
* get the collection books
*/
public Collection getBooks() {
return books;
}
/* lalinuna.de 02.11.2004
* set the collection books
*/
public void setBooks(Collection books) {
this.books = books;
}
/* lalinuna.de 02.11.2004
* reset the collection books
*/
public void reset(ActionMapping arg0, HttpServletRequest arg1) {
books = new ArrayList();
}
}
Wir definieren in der Action Form Klasse eine Collection books und erstellen für diese einen
Getter und Setter. In der Methode reset initialiseren wir die Collection mit einem neuen ArrayList.
Erstellen eines Action Mappings und einer Action Klasse
Öffne die struts-config.xml und erstelle ein neues Action Mapping.
Use Case bookList, wähle Create new Action Class
Superclass org.apache.struts.Action
Wähle unter Optional Details das Form Bean bookListForm aus und bei Input Source die JSP
Datei /jsp/bookList.jsp
Erstelle noch ein Forward für das Action Mapping auf die JSP Datei mit dem Namen showList
Im Package de.laliluna.tutorial.library.action befindet sich jetzt die Action Klasse
bookListAction.
Klasse zum Bereitstellen von Testdaten hinzufügen
Wir werden in diesem Tutorial keine Datenbank benutzen. Kopiere dafür bitte aus dem Quellkode
(Download siehe oben) die Java Klasse simulateDB.java und füge sie in das Package
de.laliluna.tutorial.library ein.
Bearbeiten des Quelltextes der Action Klasse
Öffne die Klasse bookListAction und ändere die Methode execute ab.
Mit dem Aufruf mapping.findForward("showList") suchen wir ein lokales Forward mit dem
Namen showList, welches wir vorher beim Action Mapping angelegt haben.
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
BookListForm bookListForm = (BookListForm) form;
/* lalinuna.de 03.11.2004
* init SimulateDB class and set some dummy data
*/
SimulateDB simulateDB = new SimulateDB();
bookListForm.setBooks(simulateDB.getAllBooks(request.getSession()));
return mapping.findForward("showList");
}
Ausgabe der Testdaten in der JSP Datei
Öffne die bookList.jsp und füge folgenden Quelltext ein.
<%@ page language="java"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<html>
<head>
<title>Show book list</title>
</head>
<body>
<table border="1">
<tbody>
<%-- set the header --%>
<tr>
<td>Author</td>
<td>Book name</td>
<td>Available</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<%-- check if book exists and display message or iterate over books --%>
<logic:empty name="bookListForm" property="books">
<tr>
<td colspan="5">No books available</td>
</tr>
</logic:empty>
<logic:notEmpty name="bookListForm" property="books">
<logic:iterate name="bookListForm" property="books" id="book">
<tr>
<%-- print out the book informations --%>
<td><bean:write name="book" property="author" /></td>
<td><bean:write name="book" property="title" /></td>
<td><html:checkbox disabled="true" name="book" property="available" />
</td>
<%-- print out the edit and delete link for each book --%>
<td><html:link action="bookEdit.do?do=editBook" paramName="book"
paramProperty="id" paramId="id">Edit</html:link></td>
<td><html:link action="bookEdit.do?do=deleteBook" paramName="book"
paramProperty="id" paramId="id">Delete</html:link></td>
</tr>
</logic:iterate>
</logic:notEmpty>
<%-- end interate --%>
</tbody>
</table>
</body>
</html>
Mit dem Tag <logic:iterate> loopen wir über die Collection books unseres Form Beans
bookListForm. Innerhalb des <logic:iterate> Tags können wir über den Namen book auf
die Eigenschaften der Book Klasse zugreifen. Der Tag <bean:write> schreib eine Eigenschaft
(Autor, Titel) an die aktuelle Stelle. <html:checkbox> erstellt eine Checkbox.
Es ist geschafft puhhhh, wir haben unser Form Bean mit Action Form Klasse, unser Action
Mapping mit Action Klasse und unsere JSP, die uns zur Anzeige dient, angelegt.
Anwendungsfall Hinzufügen, Bearbeiten und Löschen von Daten
Im nächsten Schritt wollen wir Daten hinzufügen, bearbeiten und löschen.
Neues Form Bean
Lege dazu ein neues Form Bean, mit einer neuen Action Form Klasse an. Vergib den Use case
bookEdit. Wähle unter Optional details – Methods keine Methode aus. Unter JSP
lassen wir wieder die JSP erstellen.
Öffne die Klasse BookEditForm.java unter de.laliluna.tutorial.library.form .
Erstelle eine neue Instanz book der Klasse Book.
Book book = new Book();
Generiere für die Intanz einen Getter und Setter. Und delegiere alle Methoden der Klasse Book
Der Quelltext sieht wie folgt aus:
public class BookEditForm extends ActionForm {
Book book = new Book();
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public boolean equals(Object arg0) {
return book.equals(arg0);
}
public String getAuthor() {
return book.getAuthor();
}
public long getId() {
return book.getId();
}
public String getTitle() {
return book.getTitle();
}
public int hashCode() {
return book.hashCode();
}
public boolean isAvailable() {
return book.isAvailable();
}
public void setAuthor(String author) {
book.setAuthor(author);
}
public void setAvailable(boolean available) {
book.setAvailable(available);
}
public void setId(long id) {
book.setId(id);
}
public void setTitle(String title) {
book.setTitle(title);
}
public String toString() {
return book.toString();
}
}
Damit ist die Klasse Book der Action Form Klasse zugewiesen und man kann später im Formular
auf die Eigenschaften zugreifen.
Action Mapping
Erstelle ein neues Action Mapping. Einen kleinen Unterschied gibt es bei unserer neuen Action
Klasse. Diese leitet sich nicht wie vorher von der Superclass org.apache.struts.Action ab,
sondern in diesem Falle von der Klasse org.apache.struts.DispatchAction.
Eine DispatchAction erlaubt uns unterschiedliche Methoden aufzurufen, statt nur der execute
Methode.
Mit einem Parameter können wir steuern, wann die create/edit/delete Methode aufgerufen wird.
Unter Parameter vergeben wir einen Parameter do. Dieser wird von unserer DispatchAction
Klasse benötigt. Mehr dazu später.
Richte unter Forward drei neue Forwards ein. Zum einen für die JSP Datei zum Bearbeiten. Ein
Zweites für das Anlegen eines Buches und zu guter letzt ein Forward, dass uns wieder auf die
Bücherübersicht leitet.
Das letzte Forward weist nicht wie üblich auf eine JSP Datei, sondern direkt auf ein vorhandes
Action Mapping.
Erstelle im Anschluss eine neue JSP Datei bookAdd.jsp im Verzeichnis /WebRoot/jsp. Auf
diese JSP verweisst unser Forward showAdd.
Erstellen des Quelltextes für die JSP Dateien
Öffne die Datei bookAdd.jsp und füge folgenden Quelltext ein.
<%@ page language="java"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>
<html>
<head>
<title>Add a book</title>
</head>
<body>
<%-- create a html form --%>
<html:form action="bookEdit">
<%-- print out the form data --%>
<table border="1">
<tr>
<td>Author:</td>
<td><html:text property="author" /></td>
</tr>
<tr>
<td>Title:</td>
<td><html:text property="title" /></td>
</tr>
<tr>
<td>Available:</td>
<td><html:checkbox property="available" /></td>
</tr>
<tr>
<td colspan="2">
<html:submit>Save</html:submit>
</td>
</tr>
</table>
<%-- set the parameter for the dispatch action --%>
<html:hidden property="do" value="saveBook" />
</html:form>
</body>
</html>
Der Tag <html:form> erstellt ein neues HTML Formular und weisst mit action=“bookEdit“
auf das vorher angelegte Action Mapping. Der Tag <html:text> schreibt ein Textfeld mit der
Eigenschaft Autor unseres Buches. <html:hidden> erstellt ein Hidden Formular Feld mit Namen
do. Wir benötigen dieses Feld um unserer DispatchAction Klasse zu sagen, welche Methode sie
aufrufen soll.
Öffne die Datei bookEdit.jsp. Wir können den Quelltext von der Datei bookAdd.jsp verwenden.
Ändere folgende Zeilen ab.
<title>Edit a book</title>
Füge folgende Zeilen über <html:hidden property="do" value="saveBook" />
<%-- hidden field that contains the id of the book --%>
<html:hidden property="id" />
Das wars auch schon.
Quelltext der DispatchAction Klasse
Öffne die Datei bookEditAction.java. Füge folgende Methoden der Klasse hinzu.
/**
* Method editBook
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward editBook(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
BookEditForm bookEditForm = (BookEditForm) form;
/* lalinuna.de 04.11.2004
* get id of the book from request
*/
long id = Long.parseLong(request.getParameter("id"));
/* lalinuna.de 04.11.2004
* init SimulateDB class and get book by id
*/
SimulateDB simulateDB = new SimulateDB();
bookEditForm.setBook(simulateDB.loadBookById(id, request.getSession()));
return mapping.findForward("showEdit");
}
Die Methode editBook ruft die übergebene id aus dem request ab und liest das Buch aus der
simulierten Datenbank. Das Forward showEdit verweist danach auf die JSP Datei zum Editieren.
/**
* Method deleteBook
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward deleteBook(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
BookEditForm bookEditForm = (BookEditForm) form;
/* lalinuna.de 04.11.2004
* get id of the book from request
*/
long id = Long.parseLong(request.getParameter("id"));
/* lalinuna.de 04.11.2004
* init SimulateDB class and delete book by id
*/
SimulateDB simulateDB = new SimulateDB();
simulateDB.deleteBookById(id, request.getSession());
return mapping.findForward("showList");
}
Die Methode deleteBook ruft die übergebene id aus dem request ab und löscht das Buch aus
der simulierten Datenbank. Danach verweist das Forward showList auf die Bücherübersicht.
/**
* Method addBook
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward addBook(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
BookEditForm bookEditForm = (BookEditForm) form;
return mapping.findForward("showAdd");
}
Die Methode addBook verweist auf die angelegte bookAdd.jsp
/**
* Method saveBook
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward saveBook(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
BookEditForm bookEditForm = (BookEditForm) form;
/* lalinuna.de 04.11.2004
* init SimulateDB class and get data by id
*/
SimulateDB simulateDB = new SimulateDB();
simulateDB.saveToDB(bookEditForm.getBook(), request.getSession());
return mapping.findForward("showList");
}
Die letze Methode saveBook liest die Instanz book aus dem Form Bean BookEditForm und ruft
eine Methode saveToDB zum Speichern des Buches auf. Danach wird auch hier auf die
Bücherübersicht verwiesen.
Bearbeiten der Bücherübersicht
Öffne die Datei bookList.jsp und ändere den Quelltext wie folgt ab.
<%@ page language="java"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<html>
<head>
<title>Show book list</title>
</head>
<body>
<table border="1">
<tbody>
<%-- set the header --%>
<tr>
<td>Author</td>
<td>Book name</td>
<td>Available</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<%-- check if book exists and display message or iterate over books --%>
<logic:empty name="bookListForm" property="books">
<tr>
<td colspan="5">No books available</td>
</tr>
</logic:empty>
<logic:notEmpty name="bookListForm" property="books">
<logic:iterate name="bookListForm" property="books" id="book">
<tr>
<%-- print out the book informations --%>
<td><bean:write name="book" property="author" /></td>
<td><bean:write name="book" property="title" /></td>
<td><html:checkbox disabled="true" name="book" property="available" />
</td>
<%-- print out the edit and delete link for each book --%>
<td><html:link action="bookEdit.do?do=editBook" paramName="book"
paramProperty="id" paramId="id">Edit</html:link></td>
<td><html:link action="bookEdit.do?do=deleteBook" paramName="book"
paramProperty="id" paramId="id">Delete</html:link></td>
</tr>
</logic:iterate>
</logic:notEmpty>
<%-- print out the add link --%>
<tr>
<td colspan="5"><html:link action="bookEdit.do?do=addBook">Add a new
book</html:link>
</td>
</tr>
<%-- end interate --%>
</tbody>
</table>
</body>
</html>
Damit haben wir unsere kleine Beispielanwendung beendet und wir können diese nun testen.
Testen der Anwendung
Starte den Jboss und Deploye das Projekt als Package Archive
Rufe jetzt im Webbrowser das Projekt aus http://localhost:8080/LibraryWeb/
Gratulation, das wars .... ;)

Documents pareils