Using Open Source in Java
Projects
Jay Sissom jsissom@indiana.
edu
Agenda
Expectations
Why Open Source
Tools Overview
Example Application
Open Source Tools
Ant
jRelational Framework
Struts
jUnit
Summary
Expectations
You will NOT be a pro on these
tools in 3-1/2 hours!
You will NOT learn Java today
You will get an idea of how these
tools can work in your environment
You will take home a CD with a
copy of all the libraries and
samples we are using today
Why Use Open Source
Arguments Against Open Source
“No one to sue”
“You get what you pay for”
“No vendor support”
Why Use Open Source
Arguments For Open Source
Why re-invent the wheel?
No $$$ expenditures
Great support via internet (mostly)
Source is available to review design
You may be able to resolve problems
faster than a vendor would
Open Source Tools
Overview
Ant – automated source code
building tool (make for Java)
jRelational Framework – Object to
database mapping framework
jUnit – Unit testing framework
Struts – Model/View/Controller user
interface framework
Other Open Source Tools
Log4j - Logging
Hsql – 100% Java relational
database
Tomcat – Web server, Servlet
container
NetBeans – IDE for Java
These are just the
tip of the iceberg!
Example Application
Personal Address Book Application
Lookup people in an LDAP directory (or
database)
Add personal notes for people
Web based user interface
Built with ant, using Struts and jRelational
Frameworks, tested with jUnit
Thanks to Southern Illinois University for the
use of their LDAP directory for this example.
Example Application
(continued)
Tools used in application
Sun JDK 1.4.1
Total Cost:
jRelational Framework 1.7 $0
Struts 1.0.2
Hsql Java database
Log4j Logging
Tomcat Servlet container
Ant 1.5 to build application
jUnit 3.8.1 for testing
NetBeans Java IDE (optional)
LDAP directory (optional)
What is Ant?
Tool to Build an application
Similar to the make utility on Unix
systems
Written in Java
Configured using XML
What’s wrong with make?
File format difficult to use
Not platform independent
Relies on shell scripts for complex
tasks that can be even LESS
platform independent
Starting a JVM is time consuming
Ant to the rescue
Ant uses XML for the file format
Ant is a Java application
The JVM starts once and is used for
all tasks (unless you tell it not to)
Complex tasks can be written in
Java for operating system
independence
Example Ant Build File
<?xml version=“1.0”?>
<project name=“Simple Buildfile” default=“compile” basedir=“.”>
<property name=“src.dir” value=“src”/>
<property name=“classes.dir” value=“classes”/>
<property name=“build.dir” value=“build”/>
<target name=“prepare”>
<mkdir dir=“${classes.dir}”/>
<mkdir dir=“${build.dir}”/>
</target>
<target name=“compile” depends=“prepare” description=“Compile Code”>
<javac srcdir=“${src.dir}” destdir=“${classes.dir”/>
</target>
<target name=“jar” depends=“compile” description=“Build JAR file”>
<jar jarfile=“${build.dir}/output.jar” basedir=“$classses.dir”/>
</target>
<target name=“clean” description=“Clean compiled code”>
<delete dir=“${build.dir}”/>
<delete dir=“${classes.dir}”/>
</target>
<target name=“all” depends=“clean,jar” description=“Builds everything”/>
</project>
Build file components -
project
Provides:
Name of the project
Default target to use if none are specified
Base directory for project
One per build file
This component holds targets
Example:
<project name=“My Killer App” default=“compile”>
…
</project>
Build file components -
target
A target is one unit of work
A target contains one or more task
A target can depend on other
targets
Example:
<target name=“compile” depends=“prepare”>
…
</target>
Build file components -
task
A task actually does some work
Each task takes it’s own set of
parameters
You can write your own tasks in
Java if necessary
Example tasks that come with ant:
mkdir, delete, javac, javadoc, jar, war,
ear, cvs, mail, unzip
Build file components -
task
Tasks that come in the optional.jar
file
cab – create a .cab file
csc – compile c# code
ftp – ftp files
junit – run junit tests
rpm – builds a Linux rpm
There are lots more!
Build file components –
other
Property
A name-value pair
<property name=“build.dir” value=“build”/>
Use ${build.dir} to reference it
Build file components -
other
Path and File lists
<path id=“classpath”>
<fileset dir=“${lib.dir}”>
<include name=“activation.jar”/>
<include name=“serlvet.jar”/>
</fileset>
</path>
<path id=“second_classpath”>
<fileset dir=“${lib.dir}”>
<include name=“**/*.jar”/>
<exclude name=“junit.jar”/>
</fileset>
</path>
Running ant
Command line:
ant target
Used if your build file is named build.xml
in the current directory
ant –buildfile filename target
Used if your build file isn’t named
build.xml or in a different directory
Run from within a supporting IDE
Example Program Directory
Structure
(root)
src properties test ldap testclasses dist
javadoc
WEB-INF
lib classes
Example ant script – init
target
<target name="init">
<property file="../build.compile.ant.properties"/>
<property name="webapp" value="ldap"/>
<property name="classes" value="${webapp}/WEB-INF/classes"/>
<property name="lib" value="${webapp}/WEB-INF/lib"/>
<property name="src" value="src"/>
<property name="test" value="test"/>
<property name="testclasses" value="testclasses"/>
<property name="properties" value="properties"/>
<property name="dist" value="dist"/>
…
Example ant script – init
target
…
<!--- Path to compile the application -->
<path id="compile.classpath">
<!-- Include all elements that Tomcat exposes to
applications -->
<pathelement location="${catalina.home}/common/classes"/>
<fileset dir="${catalina.home}/common/lib">
<include name="*.jar"/>
</fileset>
<!-- Application specific lib files -->
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</path>
…
Example ant script – init
target
…
<!-- Path to test the application -->
<path id="test.classpath">
<path refid="compile.classpath"/>
<pathelement location="${testclasses}"/>
<pathelement location="${classes}"/>
</path>
</target>
Example ant script – compile
target
<target name="compile" depends="init" description="Compile">
<mkdir dir="${classes}"/>
<javac debug="true" deprecation="true“
destdir="${classes}" srcdir="${src}">
<classpath refid="compile.classpath"/>
</javac>
</target>
Example ant script -
testcompile
<target name="testcompile" depends="compile“
description="Compile Tests">
<mkdir dir="${testclasses}"/>
<javac debug="true" deprecation="true“
destdir="${testclasses}" srcdir="${test}">
<classpath refid="test.classpath"/>
</javac>
</target>
Example ant script -
javadoc
<target name="javadoc" depends="init" description="Javadoc">
<mkdir dir="apidoc"/>
<javadoc destdir="apidoc" packagenames="edu.*">
<sourcepath>
<pathelement location="${src}"/>
</sourcepath>
<classpath refid="compile.classpath"/>
</javadoc>
</target>
Example ant script - dist
<target name="dist" depends="init,compile“
description="Build Distribution File">
<mkdir dir="${dist}"/>
<jar jarfile="${dist}/ldap.war" basedir="${webapp}">
<exclude name="WEB-INF/lib/junit.jar"/>
</jar>
</target>
Example ant script - all
<target name="all" depends="init,dist" description="Build everything.">
<echo message="Application built"/>
</target>
Example ant script - test
<target name="test" depends="init,compile,testcompile“
description="Junit tests">
<java fork="yes" classname="junit.textui.TestRunner“
taskname="junit" failonerror="true">
<arg value="edu.iu.uis.sit.ldapsearch.test.AllTests"/>
<classpath refid="test.classpath" />
</java>
</target>
Example ant script - clean
<target name="clean" depends="init"
description="Clean all build products">
<delete dir="${classes}"/>
<delete file="${dist}/ldap.war"/>
<delete dir="apidoc"/>
<delete dir="${dist}"/>
<delete dir="${testclasses}"/>
</target>
Ant Summary
Allows developers to build the
application consistently no matter
what environment, operating
system
jRelational Framework (jrf)
Open Source Framework
Object/Database mapping
Framework
Automates most of SQL
programming
Tables look like objects to
programmers
jrf Provides
Object-to-relational mapping for:
Sequenced primary keys
Natural primary keys
Compound primary keys
Insertion of a new object instance into the database.
Updating of existing object instances.
Deleting of existing object instances.
Finding of persistent instances by primary key.
Finding all persistent instances. (Finding all rows in a
table).
Finding of a portion of persistent instances that match
an application-specific criteria.
Augmentation of persistent object instances with
columns from other tables (Joining of tables).
jrf Provides
Aggregation - creation of multiple objects from one
result set.
Flexibility to define custom SQL queries for specialized
searches.
Database independent validation of objects based on
the metadata defined in the AbstractDomain subclass.
(i.e. REQUIRED and UNIQUE field constraints).
Database independent defaulting of attribute values
when updating and selecting from the database.
Optimistic locking of an object/row using a Timestamp
or Integer column. When conflicts occur, an
ObjectHasChanged exception is thrown by the
framework.
Linking of related objects at retrieval time through the
jrf Provides
Plenty of "hooks" by which you can customize
your object before saving, after saving, after
finding, etc...
Compatible with database triggers that change
the tables.
Generation of basic PersistentObject and
AbstractDomain subclasses from an existing
database (using the jrf-extras jar).
Connection pooling (Either via the included
JDBCHelperPool or via your application server
pooling).
Object Mapping
Each RDBMS table is mapped to
two objects
Persistent Object (or Entity Object)
which represents one row
Domain Object which represents the
entire table
Entity Object
Is a JavaBean
Has a property for every column in a
table
The setter method must contain a call
to this.markModifiedPersistentState();
Each property MUST be a Java Object,
not a built in java type
Parent object is
com.is.jrf.PersistentObject
Domain Object
Represents an entire table
Has a method to return lists of all rows
Has a method to return a single row via the
primary key
Has a method to return a list of rows based on
a specified where clause
Has method to add, update or delete single
row
Parent object is com.is.jrf.AbstractDomain
A Domain object can have “hooks” for various
events in the object lifecycle
JDBCHelper
JDBCHelper is the jrf class to wrap
a JDBC driver
You’ll need to work with
JDBCHelper any time you talk to
the database
JDBCHelpers will also let you
manage database transactions
Creating a Domain Object
Create a subclass of
com.is.jrf.AbstractDomain
Implement a protected void
setup() method which should
set the DatabasePolicy
set the table name
Add Column specs for each column
Creating a Domain Object
Override the newPersistentObject
method and return a new instance
of your entity object
Column Specs
Each column in the table needs to
be defined in the setup method of
the Domain object
There are ColumnSpec objects for
many different data types:
StringColumnSpec
IntegerColumnSpec
LongColumnSpec
Column Specs
The constructor for a xColumnSpec
object needs the following
parameters:
column name
getter method name
setter method name
default value
zero or more options
Column Specs – default
value
Default Value constants
DEFAULT_TO_NULL
DEFAULT_TO_EMPTY_STRING
DEFAULT_TO_ZERO (Integer only)
DEFAULT_TO_ONE (Integer only)
DEFAULT_TO_NOW
DEFAULT_TO_TRUE
DEFAULT_TO_FALSE
Column Specs - options
Option constants
SEQUENCED_PRIMARY_KEY
NATURAL_PRIMARY_KEY
OPTIMISTIC_LOCK
REQUIRED
UNIQUE
Max of 3 options
Primary key options shouldn’t be used
with other options (Required & Unique
assumed)
Column Specs
The Domain object has a method
called addColumnSpec that lets
you add each Column Spec object
this.addColumnSpec(new
StringColumnSpec(“user_nm”,
”getUser_nm”,”setUser_nm”,
DEFAULT_TO_EMPTY_STRING,REQUIRED)
Finders
Finders allow you to retrieve lists
of rows that meet certain
requirements
jrf supplies a finder by primary
key, a finder for all rows, and one
for a where clause
You’ll need to write additional ones
Finder methods belong in the
Domain object
Finders
Example Finders
findByUserNm(String user_nm)
findByID(Integer id)
findByAccount(String fin_coa_cd,
String account_nbr)
findNamesStartingWith(String s)
Finders
jrf provides a findWhere method
Example findByUserNm method
public List findByUserNm(String
user_nm,JDBCHelper j) {
String user =
JDBCHelper.delimitString(user_nm,”’”);
return this.findWhere(this.getTableAlias() +
“.user_nm = ” + user,j);
}
Order By
Often we need to return data in a
special order
jrf provides a findOrderBy method to
find all with an ORDER BY clause
jrf also provides a findWhereOrderBy
method to find specified rows with an
ORDER BY clause
Pass a list of column names separated
by commas for the orderByString
parameter
Locking
Pessimistic locking – lock a row
before modifying it just in case
someone else will want to modify
the row while we are
Optimistic locking – Assume that
no one will modify the row while
we’re changing it and check if they
did after the fact
Optimistic Locking
Method 1
Add a Timestamp column for each
table and update it for each UPDATE
Grab the Timestamp from a row. Let
the user modify the row, then specify
the original Timestamp in the where
clause
Optimistic Locking
Method 2
Add a version number column for
each table and increment it for each
UPDATE
Grab the version number from a row.
Let the user modify the row, then
specify the original version number in
the where clause
Optimistic Locking
Each table will have an
NUMERIC(8) column named
jrf_ver_nbr
jrf will automatically handle
Optimistic Locking if we tell it to:
this.addColumnSpec(new IntegerColumnSpec("JRF_VER_NBR","getJrf_ver_nbr",
"setJrf_ver_nbr",DEFAULT_TO_ZERO,OPTIMISTIC_LOCK));
Optimistic Locking
We must provide a getter/setter
for jrf_ver_nbr in the Entity object
jrf will throw an
ObjectHasChangedException if the object
changes between the time you
retrieve the data and update the
data
It’s up to you to determine how
your application will react
Optimistic Locking
When you retrieve data from an
Entity to be edited, you must make
sure the jrf_ver_nbr gets retrieved
maintained until you save it
Transactions
By default, each SQL command
happens by itself
Sometimes a group of actions ALL
need to happen or NONE happen
Database Transactions allow us to
support this functionality
create table bc2_account_t (
user_nm varchar2(8) not null,
account_nbr varchar(7) not null,
Transactions );
balance_amt numeric(8) not null
Example: Transfer money between
two accounts
update jay_account_t set balance_amt =
balance_amt – 10 where user_nm = ‘jsissom’ and
account_nbr = ‘SAVING’
update jay_account_t set balance_amt =
balance_amt + 10 where user_nm = ‘jsissom’ and
account_nbr = ‘CHECK’
Both have to happen or neither
have to happen
Transactions
Database managed transactions
(by default):
begin transaction (implied)
update jay_account_t set balance_amt =
balance_amt – 10 where user_nm = ‘jsissom’ and
account_nbr = ‘SAVING’
commit (implied)
begin transaction (implied)
update jay_account_t set balance_amt =
balance_amt + 10 where user_nm = ‘jsissom’ and
account_nbr = ‘CHECK’
commit (implied)
Transactions
Developer managed transactions:
begin transaction
update jay_account_t set balance_amt = balance_amt – 10
where user_nm = ‘jsissom’ and account_nbr = ‘SAVING’
update jay_account_t set balance_amt = balance_amt + 10
where user_nm = ‘jsissom’ and account_nbr = ‘CHECK’
commit
If the commit never happens, the
database will rollback the transaction
The developer can rollback the
transaction if there is a problem
jrf Transactions
By default, jrf will automatically
begin transactions, commit
transactions or rollback for each
database operation by itself
Each operation has it’s own
transaction
jrf Transactions
Each database action in jrf can
possibly use a different connection
to the database because
connections come from the pool
A transaction cannot span multiple
connections
To manage a transaction, you also
need to manage the connection
jrf Transactions
Example jrf code without
transactions:
JDBCHelper jdbcHelper = getJDBCHelper();
checkingAccount.setBalance_amt(checkingAccount.getBalance_amt()
try {
Account nAccount1 = aDomain.save(checkingAccount,jdbcHelper);
}…
savingAccount.setBalance_amt(savingAccount.getBalance_amt()+10)
try {
Account nAccount2 = aDomain.save(savingAccount,jdbcHelper);
}…
jdbcHelper.close();
jrf Transactions
Example code WITH transactions:
JDBCHelper jdbcHelper = getJDBCHelper();
jdbcHelper.beginTransaction();
checkingAccount.setBalance_amt(checkingAccount.getBalance_amt(
try {
Account nAccount1 = aDomain.save(checkingAccount,jdbcHelper);
}…
savingAccount.setBalance_amt(savingAccount.getBalance_amt()+10
try {
Account nAccount2 = aDomain.save(savingAccount,jdbcHelper);
}…
jdbcHelper.endTransaction();
jdbcHelper.close();
jrf Transactions
Oracle (and most other RDBMS’s)
by default will “hide” any changes
made within a transaction until the
transaction is finished
Other database connections won’t
see these changes during the
transaction
jRF 2.0 Beta
jRF 2.0 Beta is out
It is not 100% backwards
compatible with 1.7
Check http://jrf.sourceforge.net for
more information
jRF Summary
jRF is a good lightweight
framework for mapping objects to
tables
jUnit
Unit Tests are a series of tests that
verify each component of your
application
jUnit is a framework to help
standardize these tests
jUnit can help automate tests so it
is easy to see if a component
works
jUnit can be integrated into ant
Why Unit Test?
Find bugs soon after code is
written
Save other team members’ time
Prove that finished code works
Make future maintenance easier
Example of how to use code
Unit testing goals
Each class has tests for all public
methods
Tests not only test successes, but also
test failures
Tests are organized so they are easy to
run
Tests are run often
Each test is completely independent of
other tests
Each time a bug is found, write an
additional test to check for that bug,
jUnit Concepts
TestCase – a series of related tests
All the tests for an object
All the tests for a method
TestSuite – a series of related test
cases
All tests for a package
All tests for an application
jUnit Concepts
Fixtures – routines that setup the
environment for each test
Create database connections
Initialize the environment
TestRunner – jUnit code that runs
tests
Command line
Swing
jUnit Addons
Dbunit – code to initialize a database to
a known state before testing
Struts test case – Test Struts specific
code using mock objects
Cactus – Test HTTP applications using
mock objects
HttpUnit – Test HTTP applications based
on an embedded servlet container
Writing jUnit tests
1. Subclass
junit.framework.TestCase
2. Create a constructor with a single
String parameter. Call
super(string) in this constructor
3. Write tests in methods that return
void and start with test as their
name
4. Call fail, assertX in tests as
Test success/failure
assertX methods test for the
correct values. Examples:
assertTrue/assertFalse
assertNull/assertNotNull
assertEquals
Fail method stops the test and
marks it as a failure
Test success/failure
The assertX and fail methods will
take an optional string to describe
the test
I recommend you ALWAYS use this
string to document the tests
Example test
/**
* Test searching for someone that doesn't exist
**/
public void testGetPerson1() {
try {
BusinessLogicInt bli =
BusinessLogicFactory.getInstance(getImplementationClass());
Person p = bli.getPerson("Unknown");
assertNull("Unknown person should be null",p);
} catch (Exception e) {
fail(e.getMessage());
}
}
jUnit Example
Look at example program
jUnit Summary
jUnit helps you create higher
quality software
Time spent by writing tests will be
recovered many times over during
future maintenance
What is Struts?
Open Source Framework
User Interface Framework based on
Model-View-Controller model (MVC or
Model 2)
Part of the Jakarta project sponsored by
the Apache Group
We will talk about Struts 1.0.2. 1.1b2
has been released with many new
features
Why use Struts
Consistency across applications
Split up HTML from Java code
Make Maintenance of applications
easier
Take advantage of code in the
framework
What is Struts?
Struts Components
Struts Servlet
Action Object (Controller)
Form Object (Model)
JSP Page (View)
Tag Libraries
Configuration File
Application Resources
Struts Servlet
“Traffic Cop” for application
Routes requests to appropriate
object
Configuration comes from
configuration file (struts-
config.xml)
Action Object (Controller)
Action objects handle every
request
Each request type should have an
action object
These are NOT Servlets
They are called by the Struts
Servlet
Form Object (Model)
Form objects store state
information
Data can be passed from action
objects (controllers) to JSP’s
(views) and back
Form objects are JavaBeans
JSP Page (View)
JSP Pages contain all the HTML
They use Form objects to display
data
HTML Forms put their data into
Form objects
Tag Libraries contain lots of
functionality you can use
Tag Libraries
Struts comes with many tags
These tags allow you to
manipulate form beans
provide i18n
have conditional parts of page
iterate through lists of data
You can add your own tag libraries also
Look at the JSTL – Java Standard Tag
Library
Configuration File
Allows the developer to define the
flow of an application declaratively
instead of in the code
The flow of an application can be
changed without recompiling code
Application Resources
An application resources file can contain
all of the messages that appear in your
application
This file can be translated into other
languages to provide i18n support
Helps in writing documentation and
making messages consistent
This file goes where your Java source
code goes – it goes in a package
Application Resources
Variable
Sample File:
application.title=My Application
group.error=The group {0} is invalid
error.username.missing=You must type in a username
error.password.missing=You must type in a password
username.message=Username:
password.message=Password:
submit.button.message=Save
Tag Libraries
struts-bean – Define new beans,
render beans/properties
struts-html – Create forms
struts-logic – Conditional page
generation, looping
Using Struts Tag Libraries
Insert these lines at the beginning of each .JSP that
will use these tag libraries
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
struts-bean
Contains tags that
manipulate the servlet context
environment
write out bean information to page
include/forward
Display messages from our resources
file
struts-bean Properties
id – Name of scripting variable and
scope key value
name – Scope key value
property – JavaBeans property
name
scope – Where to store or search
for bean (page, request, session or
application)
struts-bean
<bean:message>
Display a message from the
Message Resources
<bean:message key=“application.name”/>
struts-bean <bean:write>
Print out a bean or bean property
<bean:write name=“person” property=“lastName”/>
<bean:write name=“username”/>
struts-html
Contain tags that
handle form HTML elements
handle re-writing HREF’s
display User Interface errors
deal with user’s locales
struts-html <html>
Looks at browser’s locale setting
and enables i18n based on user’s
locale.
<html:html locale=“true”>
struts-html <html:errors>
Displays a single or all error
messages saved in the servlet
context
Action object/Form object can add
errors as necessary
<html:errors/>
<html:errors property=“username”/>
struts-html <html:form>
Start an HTML form where all input
is sent to a Form object
Uses JavaScript to set focus to first
field (optional)
POSTS or GETS to an action in
struts-config.xml
<html:form focus=“username” action=“/login.do”>
struts-html
Form Input
password
tags radio
button reset
cancel select
submit
checkbox
text
hidden textarea
multibox
option
options
All of these are just like their HTML counterparts
with a property attribute that work with a FormBean
struts-html <html:link>
Create <a href> and handle url re-
writing
Use to provide links to locations
within your application
<html:link page=“/editVendor.do”>
<bean:message key=“vendor.edit”/>
</html:link>
struts-logic
Contains tags that
Compare values
Iterate
Conditionally include parts of pages
struts-logic - Comparison
equal, notEqual
greaterEqual, lessEqual
greaterThan, lessThan
Compare a value to a cookie,
header, property or name
<logic:equal value=“en_US” header=“Accept-Language”>
You speak English, dude!
</logic:equal>
struts-logic - Exists
exists, notExists
Tests if objects exist in page,
request, session or application
state
Tests if a cookie exists
<logic:notPresent name="org.apache.struts.action.ERROR">
<bean:message key=“message.noerrors"/>
</logic:notPresent>
<logic:present name="org.apache.struts.action.ERROR">
<B><html:errors/></B>
</logic:present>
struts-logic – Substring
Matching
match, notMatch
Match on substrings
<logic:match header=“Referer” value=“myiu.iu.edu”>
I’m glad you use the Portal to access this application!
</logic:match>
<logic:notMatch header=“Referer” value=“myiu.iu.edu”>
Next time, try to access this app via the Portal!
</logic:notMatch>
struts-logic - iterate
Iterate through a list of items
<logic:iterate id="myElement" name="list">
<bean:write name="myElement"/><br/>
</logic:iterate>
Struts Configuration
Configuration in XML file
Sections of file
data-sources – JDBC Database
sources
form-beans – list of all form beans
used in app
global-forwards – list of forwards used
throughout application
action-mappings – list of all actions
and how they map to views/forms
Action Mappings
Each action object needs to have
an entry in the struts config file
Add Members -->
tion path="/AddNewMember"
pe="edu.iu.uis.sit.test.AddMemberAction"
me="MemberForm" <!– List Members -->
ope="request“ <action path="/ListMembers"
put="AddMember.jsp" type="edu.iu.uis.sit.test.ListMembersAction
lidate="true">
orward name="success" path="index.jsp"/>
ction>
Input/Edit Form List Rows Form
Action Definitions
path – path of submitted request
type – Java class of Action object to call
forward/include – path of servlet or JSP
that will handle this request
name – Name of form bean to use
input – Path to input form in case of
errors
scope –area to be used for form bean
(“request” or “session”)
validate – true/false – Validate form
bean
Bold - Required
Action Forwards
A forward is a logical definition of a
path
<forward name="success“ path="index.jsp"/>
• name = logical name
• path = path to go to
Your Action Object can refer to the logical name to
transfer control. You don’t have to hardcode a
destination path in your source code.
return (mapping.findForward(“success"));
Action Forwards
Example – Wizard Interface
If user presses Previous button, go to
previous screen
If user presses Next button, go to
next screen
<forward name=“previous“ path=“page1.jsp"/>
<forward name=“next” path=“page3.jsp”/>
Form Objects
Each form object needs to have an
entry in the struts config file
<form-bean name="PersonForm"
type="edu.iu.uis.html1.PersonForm"/>
Global Forwards
Forwards that are used throughout
your application
Example: main menu
<global-forwards>
<forward name="logoff" path="/logoff.do" />
<forward name="logon" path="/logon.jsp" />
<forward name=“menu" path="/mainMenu.jsp" />
</global-forwards>
return (servlet.findForward(“menu"));
Before Calling the Action
Object
The Struts Servlet will:
Check in the user’s session for an
instance of a form bean listed in
struts-config.xml
If it doesn’t exist, create one
Call the setter for each property that
matches a form input field
Pass the form bean to the perform
method
Action Objects
Receives requests from client
Runs appropriate business logic
forwards to view (JSP) for display
Application Architecture
struts-config.xml
BL Controllers
Struts
Browser Action Object
Servlet Entities
Form Object Domains
JSP
ApplicationResources Tag Libraries
Tiers
UI Tier BL Tier Data Tier
Action
Domain
Form Boundary Controller Entity
JSP
Struts 1.1 beta
New Features
Multiple struts-config.xml files
Dynamic beans
Declarative exception handling
Validation framework
Tiles framework
Struts Summary
Struts will save time as an
application gets complex
Struts will save time in
maintenance
Summary
By 2003, the use of open-source
software will become a standard
part of all organizations utilizing
Java…
- Thomas Murphy
METAgroup.com
Books
Resources
Ant – http://jakarta.apache.org/ant
Jrf – http://jrf.sourceforge.net/
jUnit – http://www.junit.org/
Struts –
http://jakarta.apache.org/struts
Other Resources
Tomcat – http://jakarta.apache.org/tomcat
Hsql – http://sourceforge.net/projects/hsqldb/
Log4j – http://jakarta.apache.org/log4j
NetBeans – http://www.netbeans.org/
Dbunit – http://dbunit.sourceforge.net/
Struts test case –
http://strutstestcase.sourceforge.net/
HTTP Unit – http://httpunit.sourceforge.net/
Cactus – http://jakarta.apache.org/cactus
?
Q&A