Struts
Slides by Igor Polevoy
Web Interface Best Practices
• Minimize Java Code in JSP
– Separation of concerns (web designer/Java
developer)
• Use include mechanisms
– Include directive: : static
inclusion when pre-processing JSP
– Include action: : dynamic execution of request by included
resource
• Do not mix business logic with presentation logic
• Separate responsibilities
• Better maintainability
• Better composition
Web Interface Best Practices
• Use JSP custom tags (may have to
develop these)
– Eliminate Java code from HTML
– Easier syntax
– Improve web designers productivity
– Elements of reusable code
– Suggestions:
• Keep tag syntax simple (fewer attributes)
• Do not re-invent a wheel
Web Interface Best Practices
– Place business logic in
JavaBeans
– Do not use logic in custom tags
that is not user interface-specific
– Use MVC pattern
– Use XHTML syntax
Web Interface Best Practices
• Use Servlet filters for common tasks
– Common login
– Compression
– Authentication/Authorization
• Create a portable security model
– If cannot avoid vendor security model
• Cache results from DBMS in RowSets
Power of Frameworks
• Frameworks:
– Provides abstraction of a particular concept
– Defines how these abstractions work together
to solve a problem
– Framework components are reusable
– Organizes patterns at higher level
– Provides generic behaviour (many different
applications can be built with the use of the
same application)
JSP Model 1 Architecture
Web Browser JSP
JavaBean
Demo Model 1 example
MVC Pattern
Change notification
Change state
Model
Query state
User input
Controller
View
View selection
events
JSP Model 2 Architecture
Servlet JavaBean
Web Browser
JSP
Demo Model 2 example
Java Web UI History
• Java – based CGI - HTML mixed in Java
• Servlets – HTML mixed in Java
• JavaServer Pages – Java code mixed in
HTML
• Servlets + JSP – use of MVC pattern to
separate business logic from presentation
• Frameworks: Tapestry(servlets, it’s own
html templates), Struts, JavaServer Faces
Struts
• Framework for building Web applications
using Java
• Builds on MVC pattern
• Located at: http://jakarta.apache.org/struts/
Struts History
• Created in 2000 by Craig R. McClanahan
• Donated to ASF in 2000
• Current stable release: 1.3.5
• Soon (2006) to be released 2.0
• 1.x will be around - there is new
development, great community, many
applications are developed in 1.x
Quick Technology Overview
• HTTP Protocol (request/response)
• HTML
• The Java Language and Application
Frameworks
• JavaBeans
• Properties Files and ResourceBundles
• Java Servlets
• JavaServer Pages, JSP Tag Libraries
• XML
Struts
MVC
• Struts does not specify how to implement
Model part of MVC
• JSP and Struts Tag Libraries used for
View part of MVC
• Struts Controller implemented as:
ActionServlet and ActionMapping
Struts MVC
• 3 Major Components
– Servlet controller (Controller)
– Java Server Pages (View)
– Application Business Logic (Model)
• Controller bundles and routes HTTP
request to other objects in framework
(Actions)
• Controller parses configuration file
Struts MVC
• Configuration file contains action
mappings (determines navigation)
• Controller uses mappings to turn HTTP
requests into application actions
• Mapping must specify
– A request path
– Object type to act upon the request
View Components
• HTML
• DTO
• Struts ActionForms objects
• JavaServer Pages
• Struts Tags
• Custom Tags
• Java Resource Bundles
• Other: graphics, downloads, etc.
View Components Action Forms
• ActionForm Beans
– Extends the ActionForm class
– Create one for each input form in the application
– JavaBeans – style properties must match form entries
View Components Action Forms
• Continued
– Define a property (with associated getXxx() and setXxx()
methods) for each field that is present in the form. The field
name and property name must match according to the usual
JavaBeans conventions
– Place a bean instance on your form, and use nested property
references. For example, you have a "customer" bean on your
Action Form, and then refer to the property "customer.name" in
your JSP view. This would correspond to the methods
customer.getName() and customer.setName(string
Name) on your customer bean
Controller Components
• org.apache.struts.ActionServlet
is a main component of Struts
• org.apache.struts.action.Action
– extension of controller component
(defined in action mapping in the
configuration file)
Controller Components
Deployment descriptor for Struts
• Struts use configuration file called
– struts-config.xml
– This file provides for a configuration of
controller components (actions), resources,
model components: JavaBeans and other
resources
Controller Components
The action mapping example
Action mapping name
Model Components
• System State Beans
• A set of one or more JavaBeans classes,
whose properties define the current state
of the system
• Example: shopping cart
• In a J2EE application a model is usually
encapsulated as a layer of Session
Façades
Struts Model Components
• Accessing Relational Databases
• Struts can define the data sources for an
application from within its standard
configuration file
• A simple JDBC connection pool is also
provided (can be configured in the
configuration file)
Struts Action Forms
• Action Forms are a Java Beans
• Extends ActionForm class from Struts
Framework (makes it dependent on the
Struts API)
• Action Forms are mapped to HTML forms –
hence the name
Struts Action Forms
• Extend
org.apache.struts.action.ActionForm
• Override:
– validate() - optional
– reset() - optional
• Provide JavaBeans/style properties that
match an HTML form input/output values
Struts Actions
• For every ―action‖ in the application , a
custom ―Action‖ is defined
• These a similar to servlets
• Short – lived (for the duration of the
request)
• Stateless – do not put any state in the
Action classes
Struts Action
• FQCN:
org.apache.struts.action.Action
• Implementations subclass this class and
provide implementation of execute method:
ActionForward execute(ActionMapping , ActionForm ,
HttpServletRequest , HttpServletResponse );
Action.execute() Arguments
• ActionMapping - provides access to the information
stored in the configuration file (struts-config.xml) entry
that configures this Action class.
• ActionForm form—This is the form bean. By this
time, the form bean has been pre-populated and the
validate() method has been called and returned
with no errors (assuming that validation is turned on).
All the data entered by the user is available through
the form bean.
• HttpServletRequest request—This is the
standard JSP or Servlet request object.
• HttpServletResponse response—This is the
standard JSP or Servlet response object.
Action.execute() Return
Value: ActionForward
• ActionForward represents a destination to which the
controller, RequestProcessor, might be directed to perform a
RequestDispatcher.forward or
HttpServletResponse.sendRedirect to, as a result of
processing activities of an Action class.
• Instances of this class may be created dynamically as
necessary, or configured in association with an
ActionMapping instance for named lookup of destinations
from configuration files
RequestProcessor – the heart of
Controller (Chain of Responsibility
Pattern)
• SelectAction Determine the ActionMapping associated with this path.
• CreateActionForm Instantiate (if necessary) the ActionForm associated with this
mapping (if any) and place it into the appropriate scope.
• PopulateActionForm Populate the ActionForm associated with this request, if any.
• ValidateActionForm Perform validation (if requested) on the ActionForm associated
with this request (if any).
• SelectInput If validation failed, select the appropriate ForwardConfig for return to
the input page.
• CreateAction Create an instance of the class specified by the current
ActionMapping
• ExecuteAction This is the point at which your Action's execute method will be called.
• PerformForward Finally, the process method of the RequestProcessor takes the
ActionForward returned by your Action class, and uses it to select the next resource
(if any). Most often the ActionForward leads to the presentation page that renders the
response.
03StrutsSimple Demo
Decomposing Struts Application
(web.xml)
action
org.apache.struts.action.ActionServlet
action
*.do
index.jsp
Decomposing Struts Application
(index.jsp)
First Name:
Last Name:
Note: some HTML tags are omitted for clarity
Decomposing Struts Application
(SimpleForm.java)
Rule: Action forms in Struts must:
• Conform to the JavaBeans property name conventions
• Action forms properties must correspond to the names defined in a form
public class SimpleForm extends ActionForm
{
private String firstName;
private String lastName;
public String getFirstName()
{
return firstName;
}
... other getters and setters
}
Decomposing Struts Application
(struts-config.xml part 1)
Decomposing Struts Application
(struts-config.xml part 2)
Anatomy of a Struts Application
Web Container
Browser 2
ActionServlet Action
1
5 3 DBMS
JSP View Model
4
struts-config
Decomposing Struts Application
(SimpleAction.java)
public ActionForward execute(
ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest httpServletRequest,
HttpServletResponse
httpServletResponse) throws Exception
{
//getting posted information
SimpleForm simpleForm = (SimpleForm) actionForm;
///... - business – related processing
httpServletRequest.setAttribute("simpleForm", simpleForm);
//passing control to the next page
return actionMapping.findForward("next");
}
Request Processing
• If action mapping defined in the configuration file, the Controller
Servlet/RequestProcessor will perform the following:
• Check session or request for instance of bean of appropriate class
• If no session/request bean exists, one is created automatically
• For every request parameter whose name corresponds to the name of a
property in the bean, the corresponding setter method will be called
• The validate() method of ActionForm is called
• The updated ActionForm bean will be passed to the Action Class
execute() method when it is called, making these values immediately
available
• The execute() method must return an instance of ActionForward –
instructing the controller which is the next view (page)
• The next page is merged with data passed in request or session object, and
then renders HTML
Request Processing
4
Action
ActionForm
5
3 Model
1 6
Web Browser 2
Controller
displays page 7
struts-config JSP Page
8
Page Construction
html tags
The Tag
The tag simply generates the HTML element at the
beginning of the file. In our case, this is a very basic tag.
If this application were written to provide locale-specific text, the tag could have
been written as
Using the local=‖true‖ option causes this page to set its locale value based on the
Accept-Language header submitted by the client browser (if a locale was not
already
set).
Page Construction
html tags
The Tag
The tag generates an HTML element in the
section of the
document. The HTML element is used to assist the client browser in
correctly
forming relative URL paths if they’re present in the HTML page.
In this case, our tag rendered the following HTML:
Page Construction
html tags
The tag provides convenience and a great deal of flexibility if it makes
sense for your application to URL encode request parameters. It also automatically
handles URL encoding of Session IDs to ensure that you can maintain session state
with users who have cookies turned off in their browser.
Go Home
The HTML generated is
Go Home
Create Link by Specifying a Full URL
Generate an ―href‖ directly
Form Construction
The Basics of Form Processing
This section provides information on the following
tags:
- Render an HTML
element
- Text box INPUT element
— INPUT type=hidden element
—Place a Submit INPUT element
—Place a Submit INPUT element
which can be used to ―cancel‖ workflow
Form Construction
‖simplAction‖ - action name corresponds to action name in configuration
Form Construction
Generates HTML:
Bean form bound:
public class SimpleForm extends ActionForm
{
private String firstName;
private String lastName;
...
Form Construction
Generates:
Form Construction
Where
address is a form bean property which will be
set with a selected value
addresses – Collection type property for
inputs
Input Validation
Validation can be provided:
– FormBean.validate(ActionMapping mapping,
HttpServletRequest request)
– Directly in the Action.execute() method:
ActionMessages actionMessages = new ActionMessages();
if (simpleForm.getFirstName() == null
||simpleForm.getFirstName().equals(""))
{
actionMessages.add("firstName", new
ActionMessage("field.required"));
}
Input Validation
if (!actionErrors.isEmpty())
{
saveMessages(request, actionErrors);
return actionMapping.getInputForward();
}
getInputForward(); -> sends back name of a page
from which the Action was invoked
Strings in ActionForm
Struts converts data according to property
data type
If typed value cannot be converted to
appropriate type, then exception is thrown
Exception cannot be intercepted – happens
before validation
Best practice: all properties are Strings
Message Configuration
Resource Bundle specified in a struts-config
file:
Simple Java properties file:
message_key=Message Text
Easy to do I18N
Message Output
• - outputs all error messages
• -
outputs a message for property ―propName‖
if one exists
Global Messages
Page Global Messages:
Adding:
messages.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage(―this.message.key‖) );
Displaying:
Uploading Files
form bean
public class UploadForm extends ActionForm
{
private FormFile file;
... - setter and getter
Uploading Files
jsp
Please select local file:
Uploading Files
action
UploadForm form =
(UploadForm)actionForm;
FormFile formFile = form.getFile();
byte data[] = formFile.getFileData();
//now that you have data, you can act on the
//contents of a file
Bean Tags
The tag retrieves a cookie or cookies sent to the server
from thebrowser.
The Tag - provides access to the HTTP header
The tag enables you to explicitly get a parameter
passed into this page (either by a form submit or by arguments in the
URL).
The Tag: to gain access to the request, session, response,
Struts config, or application data. The id attribute must be one of the
strings ―request‖, ―session‖, ―config‖, ―response‖, or ―application‖).
Bean Tag Examples
The preferred language for this browser is:
Session Created =
Bean Tag
bean:message
${user.username} – JSP 2.0 EL expression
Resource Bundle:
welcome.user={0}, welcome to Acme Books
Bean Tag
bean:resource
Gets contents of a resource and assigns it to
a parameter with id=‖webxml‖
DynaActoinForms
org.apache.struts.action.DynaActionForm
config:
No need to write any Java.
Validation? There is no validate() method.
Solution1: validate in Action
Solution 2: sub-class the DynaActionForm class and add a validate() method
Solution 3: Use validation framework
Disadvantage: not type safe, typos can lead to hours of debugging (no Compile
time type checking)
DynaActionForms
inside Action
execute(...)
{
DynaActionForm myForm =
(DynaActionForm )form;
String name = (String)myForm.get(―name‖);
}
Validation Framework
Jakarta Commons Validator Framework
http://jakarta.apache.org/commons
Deployed as a Struts Plugin
Extended by Struts to provide generic
validation rules
Common Rules:
check for required fields
check for max/min size
check for the right data type
Validator Built-in Rules
required – field data provided
minlength – more than min length
maxlength – less than max length
range – in range of values
mask – correct format (takes regexp)
date – validates correct date format
email – validates correct E-Mail fromat
primitives: byte, integer, float, double, etc.
Validator Setup
Validator Files
validation-rules.xml – contains all possible
rules
validation.xml – contains mappings of forms,
properties and rules
Validator Example
DynaValidatorForm
Configure a dyna-form in struts-config.xml file
DynaValidatorForm - provides basic field validation based on an XML
file
Validator Example
action mapping
Validator Example
validation.jsp
validation.jsp (HTML omitted for clarity – see demo):
User ID:
Password
Validator Example
validation.xml
action form name
maxlength
3
resource bundle
message key
... other fields
Validator Framework
validation.jsp
• Where
userForm – name of action form defined in the struts-config.xml
userId – name of a form property being validated
validationForm.iserId.required – message key from message resource
bundle
• Also:
You can have the following in the message bundle:
validationForm.iserId.maxlength={0} exceeded maximum length.
iserId.label=User Id
In this case, the error message returned by the framework in case this
field does not pass validation would be:
User Id exceeded maximum length.
Validator Framework
validation.xml
var element is used to pass any variables to
the validation rule that is being used.
minlength minlength
maxlength maxlength
range min,max
mask mask
date datePattern
Validator Framework
mixing programmatic invocation and XML rules
class MyValidatorForm extends
DynaValidatorForm
{
...
public ActionErrors validate(ActionMapping,
HttpServletRequest)
{
super.validate(mapping, request);
...
}
Validator Framework
Adding new rules(validators)
1. Create class with public static method:
someMethod(
ValidatorAction, Field, ActionErrors,
HttpServletRequest);
2. Provide a new validator definition in the validation-
rules.xml file:
a. Validator name
b. Class name
c. Method name
d. Signature
3. Can provide JavaScript to validate on client
Validator Framework
• Struts bakes rules directly into Jakarta Validator
Framework.
• Jakarta Framework allows for any method
signature, but Struts requires exact signature –
dependency in Struts- difficult to reuse validators
in a different environment
• JavaScript can break if user disables JS in client
• Better to implement validation logic in a
framework independent manner (even if using
Jakarta Validator) and invoke validations from
validate() methods – this will lead to more
infrastructure work
Struts-Tiles
• Tool for creating reusable layouts for sites
• Open Source Project (ASF)
• Integrated with Struts
• Not Enabled by default
• Allows for tiles definitions in XML
Struts-Tiles
Need to define a Tiles plugin in struts-
config.xml:
Close to the end of file with all other plugins
Struts-Tiles
Create template JSP(template.jsp):
Struts-Tiles
Provide Tiles Definitions in the tiles-defs.xml
file:
Struts-Tiles
This definition extends .baseDef and overrides title
and content fields
Struts-Tiles
Provide Action Mapping in the
...
Looking Ahead Struts 2 - 2006?
* Improved design - All Struts 2 classes are based on
interfaces. Core interfaces are HTTP independant.
* Intelligent Defaults - Most configuration elements have a
default value that you can set and forget.
* Enhanced Results - Unlike ActionForwards, Struts 2
Results can actually help prepare the response.
* First-class AJAX support - The AJAX theme gives your
interactive applications a boost.
* Stateful Checkboxes - Struts 2 checkboxes do not
require special handling for false values.
* QuickStart - Many changes can be made on the fly
without restarting a web container.
Looking Ahead Struts 2 - 2006?
* Easy-to-test Actions - Struts 2 Actions are HTTP independant and
can be tested without resorting to mocks.
* Easy-to-customize controller - Struts 1 lets you customize the
request processor per module, Struts 2 lets you customize the request
handling per action, if you like.
* Easy-to-customize tags - Struts 2 tags can be customized by
changing an underlying stylesheet.
* Easy cancel handling - The Struts 2 Cancel button can go directly to
a different action.
* Easy Spring integration - Struts 2 Actions are Spring-aware. Just add
your own Spring beans!
* Easy Plugins - Struts 2 extensions can be added by dropping in a
JAR. No manual configuration required!
Looking Ahead Struts 2 - 2006?
* POJO forms - No more ActionForms!
Use any JavaBean you like or put
properties directly on your Action. No need
to use all String properties!
* POJO Actions - Any class can be used
as an Action class. You don't even have to
implement an interface!
Struts 2.0
Bottom Line:
• Integrated with WebWork
• Breaks backwards compatibility
• 1.x is deeply entrenched in enterprise
• JSF is gaining momentum
• Struts 1.x has been too long in the 1.x
mode
• Is there future for 2.0? - time will tell