First Struts Tutorial (free tools, Struts Console, JBoss IDE)

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 using free plugins like the Struts Console and the JBOSS IDE.

General

Autor:

Sebastian Hennebrüder

Sascha Wolski

http://www.laliluna.de/tutorials.html

Datum:

January, 20th 2005
Development Tools

Eclipse 3.x

Struts Console

JBOSS IDE (when using JBOSS)

Sysdeo Plugin (when using Tomcat)

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 as explained in the tutorial. Then extract the sources, we provided, to your project.

The PDF Version of the tutorial.

http://www.laliluna.de/download/first-steps-with-struts-free-tools-en.pdf

Inhaltsverzeichnis

First steps tutorial using struts and eclipse 1

Allgemeines 1

Requirements 1

Installation of the Struts Console 2

Create a Web Project 2

Adding Struts Support 2

Create a default welcome page 4

Global Action Forwards and Action Mappings 5

Usecase Book List 6

Usecase Add, edit and remove the data 15

Changes to the book list JSP 21

Testen der Anwendung 22


Requirements

We require the installation of the JBOSS IDE, when you are using JBOSS as application server. A Tutorial how to create and deploy web projects with the JBOSS IDE can you find here.

http://www.laliluna.de/articles/posts/webprojects-eclipse-jbosside-tutorial-en.html


When you are using Tomcat, you can use the Eclipse Plugin

http://www.sysdeo.com/eclipse/tomcatPlugin.html

as an alternative.

Installation of the Struts Console

Download the sources from the website

http://www.jamesholmes.com/struts/console/

Unzip the file and copy the directory

com.jamesholmes.console.struts

to the path eclipseplugins

Start Eclipse and that's it.

Create a Web Project

The creation of a web project with the JBOSS IDE is explained in the tutorial

http://www.laliluna.de/articles/posts/webprojects-eclipse-jbosside-tutorial-en.html

which was mentioned in the requirements. Explain a web project as explained there.

Adding Struts Support

For now your project is a normal J2EE project, so we need to add the struts capabilities (libraries, xml files, ...). The easiest way is to copy a blanc struts project into your project.

You can download a blanc project here.

http://www.laliluna.de/download/struts-blanc-project-1.2.zip

Unzip the content of the blanc struts project into your project in the eclipse workspace.

Actualize the project in the package explorer by clicking on the right mouse button -> command ?refresh?.

Your project looks like the following now.




Adding the struts libraries

Now you must add the libraries to your classpath. Right click on the project and select ?properties? in the context menu.

Select ?Java Build Path? and ?add jars? in the Libraries tab.





You will find the JAR files in Projekt > WebRoot > WEB-INF > lib. Use SHIFT to select multiple jar files.

The struts libraries are now listed in the package explorer.




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. If you cannot find this option, select ?other? and then JSP.

You must have installed the JBOSS IDE!

Create a new JSP in the directory WebRoot.




You will find the file index.jsp in the folder WebRoot of the project. We must add the Struts Tag Libraries to our JSP. We need Tag Libraries to use Struts Tags in a JSP. In this case we only need the Struts logic tab library. Change your JSP content to the following.

<%@page contentType="text/html" %>
<%@ page language="java"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>


<logic:forward name="welcome"/>

The logic:forward tag makes Struts look for a forward in the configuration files. When it cannot find this forward an Exception will occure. We explain Action Forwards in the next chapter.


Create a second JSP index.jsp in the directory /WebRoot/jsp.
Change the JSP to the following:


<%@ page language="java"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html locale="true">
<head>
<html:base />

<title>index.jsp</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>

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

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 configuration file struts-config.xml, which is located in WebRoot/WEB-INF. The Struts Console is opened. (If not, right click on the struts-config.xml and select ?open with?.



Click on Action Mappings and select Add.

Input /default as path and select the Action Type Forward. As Forward Path we will use our welcome page /jsp/default.jsp








In the next step we will create the Global Action Forward. Click on ?Global Forwards?, select ?add?.

Choose /default.do as path, wich is the action we specified above.






Usecase Book List

A Struts Action does always some kind of business logic and saves the result in a class of type ActionForm. The data from the ActionForm can be displayed in a JSP.

Our Action will read data from the database, save it in the action form. The JSP will display our data.

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



Thats all for our book class!

Create a form bean, action form and jsp

Create a new sub class of ActionForm. The ActionForm will hold our books to display them in the JSP.





Open the struts-config.xml and add a new form bean with the struts console. The type is our just created class.






Change the source code of the action form class.

Open the file BookListForm.java and change the source code:


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



In our class we have defined a collection books and the access methods (getters and setters).The method reset is called by struts each time a form is initialized. When your scope is request, this is at each request.

Create an action mapping and an action class.

Create a class BookListAction. This class loads the books from the database and saves it in the BookListForm.






Change the source code of the action class.

Open the class bookListAction and implement the methode execute from the super class ActionForm.
The following call mapping.findForward("showList") looks for a forward with the name ?showList? in the action mapping declaration and forwards to it.

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


Database simulation class

We will not use a real database in this tutorial but a database simulation. Copy the file SimulateDB.java from the source code which we provided as a download above to the package de.laliluna.tutorial.library.




Struts configuration for the book list

Create a new action mapping with the Struts Console. The path must begin with a slash, the typoe is the action we have just created.






Click on the Action Mapping in the Struts console to access the advanced settings.






Create a Forward for the Action Mapping of the JSP with the name showList






Create the book list JSP

Create a new JSP in the directory /jsp/ , name it bookList.jsp .

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



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.

Very good. We have create an action class which saves the data in an action form. To display the book list we have created a JSP which uses the data in the action form. Easy, isn't it.

If you like you do a first test of your application right here. Have a look at the end of the tutorial, to see how to test.

Usecase Add, edit and remove the data

In the next section we add the functionality to add, edit and remove the data. The process is the same:


New form bean

Create a new class as action form in the package de.laliluna.tutorial.library.form . Call it BookEditForm.

Add a new instance of book.

Book book = new Book();


Generate the getters and setters. Then delegate all methods from the class Book.







The source code should look like:

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



Now we can access the attributes of book later in the action form.

Create the action class

Create a new class. This time the class is not a sub class of Action but of org.apache.struts.DispatchAction.

A DispatchAction calls not the execute method but can call different methods depending on a parameter. With the parameter we can decide if the create/edit/delete method is called.




Source code of the DispatchAction class

Open the file bookEditAction.java. Add the 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

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

}

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. Then the application forwards to the book list.

Struts configuration

Create a new form bean with the Struts Console.




Create a new action mapping. As parameter specify do. This parameter is needed by the DispatchAction.




Change theAction.




Create three forwards in the ?forward tab?. One for the JSP to edit, one for the JSP to add and one which forwards to the book list.



The lost forward does not forward to a JSP but to another action.




Create a JSP bookAdd.jsp in the directory /WebRoot/jsp. The forward showAdd forwards to this page.

Change the source code of the JSP

Open the file bookAdd.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>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>



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.

<title>Edit a book</title>



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

<%-- hidden field that contains the id of the book --%>
<html:hidden property="id" />



Changes to the book list JSP

Open the file bookList.jsp and change the 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>

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



Now, you have finished all the coding and can test your application.

Testen der Anwendung

Start the jboss and deploy the project as package archiv. (We have explained this in the JBOSS IDE Webproject tutorial, mentioned above.)



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













Gratulation, you are close to be a struts expert. ;-)