About Java and JRuby Development
JEE, Spring, Guice
Hibernate, Java Persistence (JPA)
and various Web Frameworks

First Struts Tutorial using Eclipse, MyEclipse

This tutorial will explain first steps using
the web framework Apache Struts and the development environment
eclipse. We will create a simple example library application.

Generals

Author:

Sascha Wolski

Date:

November, 2st 2004
Software:
MyEclipse
3.8
Source code:

http://www.laliluna.de/download/first_steps_with_struts.zip

Using the source code.

The
source code does not include any libraries but the sources. Create a
web project, add the libraries manually or with the help of MyEclipse
and the extract the sources we provided to your project.

The
PDF Version of the tutorial.

http://www.laliluna.de/download/first_steps_with_struts_en.pdf

Table
of Content

First
steps in Struts using eclipse + MyEclipse 1

Generals 1

Create
a struts project 1

Global
Action Forwards and Action Mappings 6

Create
a object class ?book? 9

Create
a form bean, action form and jsp 13

Edit
the source code of the action form class 14

Create
an action mapping and action class 15

Class
to provide test data 16

Edit
the source code of the action class 16

Output
the test data on the jsp file 17

Add,
edit and remove the data 18

Edit
the book listing page 24

Test
the application 25


Create a
struts project

Create a new struts project with File
> New > Project or use
the shortcut Strg +
n.
Select the Wizard in J2EE
Web Project




Create
a nice name for your project




After creating the project, your Package
Explorer looks like the picture below.





For now
your project is a normal J2EE project, so we need to add the struts
capabilityies. Right click on the project and add the capabilityies
for struts with Add Struts
Capabilityies.



Change the properties Base
package for new classes and
Default
application resource




Create
a default welcome page

Ok, now we want to create a default page.
Right click (yes again) on the Folder WebRoot
in the Project and choose New
> JSP.





Set the name to index.jsp
and choose on template to use
> Standard
JSP using Struts 1.1 MyEcplise
will use the template to create the JSP File.




You will find the file index.jsp
in the folder WebRoot of
the project. On the top of the file you will find the struts tag
libraries. These includes will be use to access the tags of struts.
In your case we only need the logic tag library.




Insert the following line below the included
logic tag.

<logic:forward name="welcome" /> 


This
line will arranges struts to find a forward with the name welcome.
If the application don�t find this forward it will leads an
error. In the next section i briefly explain the action forward.

Create a second index.jsp
file in the folder /WebRoot/jsp
Change
the body of the file to the following

&lt;body&gt;<br>    Welcome!<br> &lt;br&gt;<br> &lt;html:link action="bookList"&gt;Show the booklist&lt;/html:link&gt;<br>&lt;/body&gt;

Global
Action Forwards and Action Mappings

What
is an action forward?
A
action forward can be used to forward to a jsp or action mapping.
There are two different action forwards. The global action forward
and the local action forward. You can access a global action forward
on each jsp or action class. A local action forward can only be
accessed by the assigned action class.

What
is a action mapping?

The
action mapping is the heart of struts. It managed all actions between
the application and the user. You can define which action will be
executed by creating a action mapping.

The diagram show you, how the application
server manage the request of the index.jsp
or a non existing action
mapping.




In the first
step we create a new action mapping. Open the struts-config.xml,
you will find it in the folder WebRoot/WEB-INF.
Right click in the outline window on action-mapping.












Choose Use
Case default and Action
Type Forward. The Forward
Path is the welcome page
/jsp/index.jsp





In the second step you create a global
action forward. Go back to the outline window of MyEclipse and choose
Global Forward




Choose the
Forward Scope Global
Forward. For name use the same you have set in your default page. The
Global Forward
refers to your action mapping.




You will see the following in your editor
window.

<b>&lt;global-forwards</b> <b>&gt;</b><br><b>&lt;forward name=</b>"welcome" <b>path=</b>"/default.do" <b>redirect=</b>"true" <b>/&gt;</b><br><b>&lt;/global-forwards&gt;</b><br><b>&lt;action-mappings</b> <b>&gt;</b><br><b>&lt;action</b> <b>forward=</b>"/jsp/index.jsp" <b>path=</b>"/default" <b>/&gt;</b><br><b>&lt;/action-mappings&gt;</b>



To catch all requests of non existing action
mappings, we have to add a parameter unknow=“true”
to the action forward.

<b>&lt;action-mappings</b> <b>&gt;</b><br><b>&lt;action</b> <b>forward=</b>"/jsp/index.jsp" <b>path=</b>"/default" <b>unknown=</b>"true"<b>/&gt;</b><br><b>&lt;/action-mappings&gt;</b>



Create a object class ?book?


Create a new class Book
in the package de.laliluna.tutorial.library.






The Class Book
represents a book with the properties id, author, title and
available.
Create four variables.








Create a getter and setter for each
variable. Right click in your class, Source
> Generate Getters and Setters








Choose Select
All and insertion point Last
method.




Add two constructors to the class to set the
properties on initialisation of the class.


// Contructor<br>public Book(){}<br><br>//  Contructor to initial the properties<br>public Book(long id, String author, String title, boolean available) {<br>	this.id = id;<br>      this.author = author;<br>      this.title = title;<br>      this.available = available;<br>}<br>



Thats all !




Create a form bean, action form and jsp

Open the
struts-config.xml. Right
click on Form Bean in the
outline window.





Use Case is bookList,
Superclass org.apache.struts.ActionForm.
Select only public void reset..
on methods. Set the name of the jsp file on JSP.





The
package explorer looks like the pictures below.







Edit the source code of the action form class

Open the file BookListForm.java
and add the following soure code.

public class BookListForm extends ActionForm {<br><br> 	private Collection books;<br><br>	/* lalinuna.de 02.11.2004<br> 	* get the collection books<br> 	*/<br> 	public Collection getBooks() {<br> 		return books;<br> 	}<br><br> 	/* lalinuna.de 02.11.2004<br> 	* set the collection books<br> 	*/<br> 	public void setBooks(Collection books) {<br> 		this.books = books;<br> 	}<br><br>	/* lalinuna.de 02.11.2004<br> 	* reset the collection books<br> 	*/<br> 	public void reset(ActionMapping arg0, HttpServletRequest arg1) {<br>		books = new ArrayList();<br> 	}<br>}




Define a collection books
and generate a getter and setter. In your reset
method initial the collection with an array list.



Create an action mapping and action class

Open the struts-config.xml and create a new
action mapping.






Use Case is bookList,
choose Create new Action
Class
Superclass
org.apache.struts.Action
On
Optional Details choose the Form Bean bookListForm.

The input source is /jsp/bookList.jsp



Now add a forward showList
to the action mapping.


new-actionforward.gif

You will find the action class
bookListAction in your
package de.laliluna.tutorial.library.action.



Class
to provide test data


We do not use a database in this tutorial
and want some test data. Open the source code we provided as download
and copy the class simulateDB.java
in your package de.laliluna.tutorial.library.






Edit the source code of the action class


Open the class bookListAction and edit the
method execute. The command mapping.findForward(?showList?)
will search for a local forward with the name showList



/* 
* 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”);
}







Yeah thats all, you have now created your
form bean with an action form class, an action mapping with an action
class and the jsp to display something.


Output the test data on the jsp file


Open the file bookList.jsp
and add the following source code




<%@ 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>

The tag <logic:iterate> loops over the
collection books of the
form bean bookListForm
Within
the tag <logic:iterate>
you have access to the properties of the book. The tag <bean:write>
prints out a property (author, title) on the current position.

<html:checkbox>
creates a checkbox.





Add, edit and remove the data


In the next section we add the functionality
to add, edit and remove the data.


New form bean


Create a new form bean and action form
class. Set Use case to bookEdit and remove all methods on Optional
details ? Methods. Let MyEcplise create the jsp file for us.


Open the
class BookEditForm.java in
de.laliluna.tutorial.library.form
.
Create a new instance book
of the class Book


Book book = new Book();



Generate a getter and setter and
delegate all methods of the class Book.










The
source code looks like the following.


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();
}
}





The class Book is set in the action form
class and we have access to the properties.





Action mapping

Create a new action mapping. There is a
different between our first action class. The new action class will
extends to the superclass org.apache.struts.DispatchAction.






On Parameter we add a parameter do.
These parameter is needed by the dispatch action class.






Add three new forwards. One is for the edit
page, the second for the add page, where you can add the books and
the last forward redirect the user to the book listing.










The last forward is different to the others.
It refers to an existing action
mapping and redirect the user.

Now create a new
jsp file bookAdd.jsp in
the folder /WebRoot/jsp.
The forward showAdd
forwards to this page.





Add the source code to the jsp files

Open the
file bookAdd.jsp and add
the following source code.

&lt;%@ page language="java"%&gt;<br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%&gt; <br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%&gt;<br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %&gt;<br><br>&lt;html&gt; <br> &lt;head&gt;<br> &lt;title&gt;Add a book&lt;/title&gt;<br> &lt;/head&gt;<br> &lt;body&gt;<br> &lt;%-- create a html form --%&gt;<br> &lt;html:form action="bookEdit"&gt;<br> &lt;%-- print out the form data --%&gt;<br> &lt;table border="1"&gt;<br> &lt;tr&gt;<br> &lt;td&gt;Author:&lt;/td&gt;<br> &lt;td&gt;&lt;html:text property="author" /&gt;&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;tr&gt;<br> &lt;td&gt;Title:&lt;/td&gt;<br> &lt;td&gt;&lt;html:text property="title" /&gt;&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;tr&gt;<br> &lt;td&gt;Available:&lt;/td&gt;<br> &lt;td&gt;&lt;html:checkbox property="available" /&gt;&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;tr&gt;<br> &lt;td colspan="2"&gt;<br> &lt;html:submit&gt;Save&lt;/html:submit&gt;<br> &lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;/table&gt;<br> &lt;%-- set the parameter for the dispatch action --%&gt;<br> &lt;html:hidden property="do" value="saveBook" /&gt; <br> &lt;/html:form&gt;<br> &lt;/body&gt;<br>&lt;/html&gt;




The tag <html:form>
creates a new HTML form and refers with the parameter
action=?bookEdit? to
the action mapping. The Tag <html:text>
creates a text field with the property author of the
book.
<html:hidden>
is a hidden form field with the name do. We need this hidden field,
because it tells the dispatch action class which method will called.


Open the file bookEdit.jsp.
You can use the source code of the of the file bookAdd.jsp
and change the following lines.

&lt;title&gt;Edit a book&lt;/title&gt;




Add the following line above <html:hidden
property=“do” value=“saveBook” />


<%— hidden field that contains the id of the book —%>
<html:hidden property=“id” />








Source code of the dispatch action class


Ope the file
bookEditAction.java and
add the following methods.


/* 
* 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”);

}


The method editBook get
the parameter id of the
request and reads the book
by id from the simulated database. The forward showEdit
refres to the edit page bookEdit.jsp

/** <br> * Method deleteBook<br> * @param mapping<br> * @param form<br> * @param request<br> * @param response<br> * @return ActionForward<br> */<br>public ActionForward deleteBook(<br>	ActionMapping mapping,<br> 	ActionForm form,<br> 	HttpServletRequest request,<br> 	HttpServletResponse response) {<br> 	BookEditForm bookEditForm = (BookEditForm) form;<br><br> 	/* lalinuna.de 04.11.2004<br> 	* get id of the book from request<br> 	*/<br> 	long id = Long.parseLong(request.getParameter("id"));<br><br> 	/* lalinuna.de 04.11.2004<br> 	* init SimulateDB class and delete book by id<br> 	*/<br> 	SimulateDB simulateDB = new SimulateDB();<br> 	simulateDB.deleteBookById(id, request.getSession());<br><br> 	return mapping.findForward("showList");<br><br>}<br>

The method deleteBook get
the parameter id of the
request and remove the
book by id from the simulated database. The forward showList
refres to the book listing page bookList.jsp


/* 
* 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”);

}


The method addBook
forwards on the add page 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”);

}


The last method get the book of
the form bean bookEditForm
and save it in the simulated Database.





Edit the book listing page

Open the file bookList.jsp
and change the source code.

&lt;%@ page language="java"%&gt;<br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%&gt;<br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%&gt;<br>&lt;%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%&gt;<br>&lt;html&gt;<br>&lt;head&gt;<br>&lt;title&gt;Show book list&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;table border="1"&gt;<br> &lt;tbody&gt;<br> &lt;%--  set the header --%&gt;<br> &lt;tr&gt;<br> &lt;td&gt;Author&lt;/td&gt;<br> &lt;td&gt;Book  name&lt;/td&gt;<br> &lt;td&gt;Available&lt;/td&gt;<br> &lt;td&gt;&amp;nbsp;&lt;/td&gt;<br> &lt;td&gt;&amp;nbsp;&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;%-- check if book exists and display message or iterate over books  --%&gt;<br> &lt;logic:empty name="bookListForm" property="books"&gt;<br> &lt;tr&gt;<br> &lt;td colspan="5"&gt;No books available&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;/logic:empty&gt;<br> &lt;logic:notEmpty name="bookListForm" property="books"&gt;<br> &lt;logic:iterate name="bookListForm" property="books" id="book"&gt;<br> &lt;tr&gt;<br> &lt;%-- print out the book informations --%&gt;<br> &lt;td&gt;&lt;bean:write name="book" property="author" /&gt;&lt;/td&gt;<br> &lt;td&gt;&lt;bean:write name="book" property="title" /&gt;&lt;/td&gt;<br> &lt;td&gt;&lt;html:checkbox disabled="true" name="book" property="available" /&gt;<br> &lt;/td&gt;<br> &lt;%-- print out the edit and delete link for each book --%&gt;<br> &lt;td&gt;&lt;html:link action="bookEdit.do?do=editBook" paramName="book"<br> paramProperty="id" paramId="id"&gt;Edit&lt;/html:link&gt;&lt;/td&gt;<br> &lt;td&gt;&lt;html:link action="bookEdit.do?do=deleteBook" paramName="book"<br> paramProperty="id" paramId="id"&gt;Delete&lt;/html:link&gt;&lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;/logic:iterate&gt;<br> &lt;/logic:notEmpty&gt;<br><br> &lt;%-- print out the add link --%&gt;<br> &lt;tr&gt;<br> &lt;td colspan="5"&gt;&lt;html:link action="bookEdit.do?do=addBook"&gt;Add a new book&lt;/html:link&gt;<br> &lt;/td&gt;<br> &lt;/tr&gt;<br> &lt;%-- end interate --%&gt;<br> &lt;/tbody&gt;<br>&lt;/table&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;

Congratulation, you have finished a simple
library application. Now you can test the library.





Test the application

Start the jboss and deploy the project as
package archiv.




Call the project in your favorite web
browser. http://localhost:8080/LibraryWeb/









Thats all !!