Title: Struts:The good, the bad, the ugly
1StrutsThe good, the bad, the ugly
- A detailed evaluation of Struts 1.1 and
Enterprise Web Applications. - By Paul Smith
- Ancept, Inc. (www.ancept.com)
- psmith_at_ancept.com
2Presentation Overview
- Themes
- Struts Overview (Basic Features)
- Development Challenges in 1.0
- Problem Description
- Solution in 1.1
- Example
- Architectural Challenges Struts Applications
- Problem Description
- Possible Solution
- Q A
3Themes
- Struts 1.1 provides small to medium sized
applications all the functionality they should
need out of the box - A large project team should be aware of
limitations of Struts 1.1 which may require
customized solutions - Large architecture teams may need a custom
implementation of Struts 1.1 to enterprise class
architectures
4Supporting the Themes
- To illustrate the themes
- Section 1 describes Struts basic features
- Section 2 describes the new features of Struts
1.1 and why they exist - Section 3 describes architectural challenges in
large projects and possible solutions
5Section 1-Basic Features
- Why Use A Framework
- Struts Overview
6Why Use the Struts Framework
- A pre-built framework is better than
roll-your-own - Increased productivity in JSP production
- Cleaner design
- More time on business logic
7Easier than building your own
- Probably very similar to what you would end up
building anyway - Strong industry support instead of your own
custom framework - The Struts framework is configurable so it will
probably work for your project without building
your own - Customizing open-source is simpler than building
from scratch
8JSP Productivity
- Writing pages in Struts is roughly 40-60 faster
than without struts because you use tags NOT java
code - The custom tags, form object, messages
architecture makes data display easy (for medium
sized apps) - Tiles development helps manage page complexity
9Cleaner Design
- Struts applications are easier to develop and
maintain because the design concepts are elegant - Non-technical staff better understands layout and
design - Since code is targeted at specific business
problems, the team communicates better - Design is easier to expand for very large
application architectures
10More Time on Business Logic
- Less coding of web infrastructure means more time
for business logic - Page flow design
- Action execution synchronization
- Page model objects
- Validation
- Page templates
- Focus on re-usable custom frameworks to use with
Struts (J2EE integration, Web services)
11Struts Overview
- Struts Description
- Common Infrastructure Tasks
- Struts Solutions to Infrastructure Tasks
- How does Struts works
- The Struts Configuration File
- Where does it fit in J2EE applications
- Case Study
12Struts Description
- Struts is a Web Application Framework (custom tag
libraries, servlet, xml control files) which
increase the productivity of web developers - Struts was invented by Craig McClanahan in 2000
- Struts solves common problems with web
application development by abstracting common
infrastructure tasks
13Common Infrastructure Tasks
- Page flow design and control
- Code execution framework (Command Pattern)
- Automated data objects (MVC Pattern)
- Easy to use custom tags for display
- Validation
- Page templates layout
- Re-usable text messages
- Much more
14Struts Solutions to Infrastructure
- Forwards Page flow design and control
- Actions Code execution framework (Command
Pattern) - Forms Automated data objects (MVC Pattern)
- Struts Tags Easy to use custom tags for display
- Validator Validation
- Tiles Page templates layout
- Message Resources Handles re-usable text
messages in multiple languages
15How Struts Works
16Struts Configuration
- Struts is controlled by a Configuration file
- Struts Configuration contains
- Form Definitions Data objects for JSP pages
- Forward Definitions Abstract pages for page flow
control - Action Definitions maps requests to Command
class - Message Resources Storage of common text
messages - Plug-In Definitions Startup classes used for
initializing custom functionality
17Where does Struts fit into J2EE
18Case Study
- Department of Transportation created an aircraft
registration application for internal staff (J2EE
with a 2nd Generation Framework) - 100 JSPs
- 13.5 k lines of code in the web tier (no business
logic). - 20,000 lines of code for business logic.
- 8 months of development with a team of 5
19Section 1 Conclusion
- Struts base feature-set include significant
functionality for small to medium applications - Small applications should not need to customize
Struts significantly - Form objects and Action classes provide MVC
design - Action classes house functional code
- Forwards abstract page flow control
- Form objects and Struts tags provide page display
- Tiles provides flexible page layout
- Validator provides flexible form/page level
validation - Message Resources provide re-usable text
20Development Challenges in 1.0
- Large Numbers of Form Classes
- Large teams and Resources
- Handling Errors More Flexibly
- Problems with Page Layout
- Validating Pages and Forms
- Initializing Custom Functionality
21Lots of Form Classes
- In Struts 1.0 developers had to write a custom
class for every form (generally 1 per JSP form) - Form classes are generally very simple
- Task assigned to junior programmers (drudge work)
- Form classes sometimes not consistent
221.1 Solution Dynamic Form Objects
- Declare Forms in the struts-config.xml file
- Form objects are created when the action executes
and stored in the session or request scope - Form fields are set and retrieved using the
PropertyUtils.setSimpleProperty() method or
treated as HashMap
23Dynamic Form Example
- Declaration
- ltformgt
- ltform-property name type value/gt
- lt/formgt
Java Use Public void execute(mapping, form,
) String testProp (String)PropertyUtils.getSi
mpleProperty(form, testProp) PropertyUtils.set
SimpleProperty(form, testProp, value)
24Large Teams and Resources
- It has been difficult to co-ordinate the
struts-config file and other resources with large
teams and projects - Resources declared in config file might need to
be different for portions of the application
(shippingForm) - Partitioning development teams has been somewhat
difficult
251.1 Solution Modules
- Separate, independent applications (uses
different configuration file) under default
application - Modules are based on paths (xyz.com/app/sub-app)
and web.xml entries - Created to modularize large applications
- Break modules up according to team
- Unable to share resources between modules
26Module Example
Jakarta Struts 1.1 Ready for Prime Time (PDF) by
Chuck Cavaness.
27Handling Errors
- Struts 1.0 applications had to do all of their
error handling inside the Action classes - This could mean a significant amount duplication
of error handling code - Some large apps had to customize the framework to
do flexible error handling
281.1 Solution Declarative Error Handling
- Provides global and per Action handling of errors
- Declare errors by Exception class
- Create custom error handlers by implementing
interface
29Error Handling Example
- Declaration
- ltglobal-exceptionsgt
- ltexception handler"CustomHandler"
key"error.message" path"/error.jsp"
scope"request" type"java.lang.Exception"/gt - lt/global-exceptionsgt
Java Use public ActionForward execute( Exception
ex, ExceptionConfig exConfig, ActionMapping
mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse
response ) throws ServletException handle
error return mapping.findForward(errorPage)
30Problems with Page Layout
- Struts 1.0 provided some page layout mechanism
- Large application pages can get very complicated
without a better layout mechanism - 1.0 version could not change based on Locale
- 1.0 version did not have significant re-use
functionality
311.1 SolutionTiles Integration
- Tiles code has been integrated into core Struts
- Tiles provides flexible page layout and re-use
mechanism - Provides support for Locales
- Tiles can be nested
- Tiles can be used as Struts Forwards by tile name
32Tiles Example
- Tiles-Config.xml
- ltdefinitionsgt
- ltdefinition namehome.default
path/index.jsp/gt - ltput nameheader valueheader.jsp/gt
- lt/definitiongt
- ltdefinition namehome.default
- extendshome.default/gt
- ltput nameheader valueother.jsp/gt
- lt/definitiongt
- lt/definitionsgt
Index.jsp lt_at_ taglib URIWEB-INF/tiles.tld
nametilesgt lthtmlhtmlgt ltbodygt lttilesinsert
attributeheader/gt lttilesinsert
attributebody/gt lttilesinsert
attributefooter/gt
33Validating Pages and Forms
- Struts 1.0 only provided automatic support for
validating form objects (by calling the validate
method) - Programmers had to implement validation code
inside of the class (ex. making sure phone was
really a number) by hand - Client-side validation had to be implemented by
hand
341.1 Solution Validator Integration
- Validator integrated into core code base
- Use a xml file to declaratively validate form
objects - Validators are keyed against the form by name
- Comes with many pre-built validators (e-mail,
date, etc) - Supports client-side (JavaScript) and server-side
validation
35Validator Config Example
- Struts-Config.xml
- ltform nameshippingFormgt
- ltform-property nameaddress typejava.lang.Stri
ng /gt - lt/formgt
Validator.xml ltform nameshippingFormgt ltfield
propertyaddress dependsrequired,
mask/gt ltarg0 keylabel.address/gt ltvargt
ltvar-namegtmasklt/var-namegt
ltvar-valuegt\wlt/var-valuegt lt/vargt lt/fieldgt
36Validator JSP Example
- Index.jsp
- lt_at_ taglib URIWEB-INF/tiles.tld nametilesgt
- lthtmlhtmlgt
- ltbodygt
- lthtmlform actionlogonSubmit
onsubmitvalidateLogonForm(this)gt - (this makes the form call the validation
JavaScript onSubmit) - lttablegt
- etc.
- lt/tablegt
- ltvalidatorjavascript formNamelogonForm/gt
(This inserts the javascript which executes the
validation) -
37Initializing Custom Functionality
- Often custom applications need to initialize
information when the application starts up - Since Struts runs off of a servlet this was very
difficult
381.1 Solution Plug-Ins
- Plug-Ins provide a means for initializing
components on application startup - Provide means for Factory functionality or
customization - Init-parameters let you pass information into
plug-in
39Plug-in Example
- Struts-Config.xml
- ltplug-in classnameTestPlugingt
- ltset-property propertydatasource
valuetestData/gt - ltset-property propertyuser valueuser/gt
- lt/plug-ingt
TestPlugin Code public void init(ActionServlet
servlet, ApplicationConfig config) perform
initialization Public void destroy() perfor
m shutdown
40Section 2 Conclusion
- Struts 1.1 has added significant functionality to
help medium to large application teams - Even large application teams should be able to
use Struts without actually modifying the
underlying Struts code - Plug-ins allow initialization of advanced
patterns - Declarative error handling allows re-use of error
code - Dynamic forms save tremendous effort
- Validation saves significant effort
- Modules provide large team partitioning
41Architectural Challenges
- Contextual Pages Declarative Branching
- Composable Actions
- Re-Use
- Event Handling
- J2EE Integration
- Content Management Integration
42Contextual Pages
- Sometimes the developer wants to use JSPs in
different locations in the page flow - These pages and their associated action classes
must then have large if/then blocks - Certain types of context tracking are almost
impossible without extending the framework
(dynamically modifying actions, etc)
43Contextual Pages
44Declarative Branching
45Solutions Context Subsystem
- Create Context object which tracks the path the
user has traveled - Create ContextualAction super-class which adds
the page and action to the context - Make all Action classes subclass ContextualAction
and use path history for logic
46Composable Actions
- Actions are currently made up of only one class
file - To partition an Action the developer must use
large if/then blocks and Request properties - The developer must put all of this code in one
action or write custom JavaScript to call
different actions based on the users mouse-click - This is not made easy for the developer and can
cause problems if not thought through early on
47Composable Actions
48SolutionComposable Actions
- Some amount of composition can be achieved
using local ActionForwards - Better composition can be achieved with the
Struts Action Plug-in Extension 1.0.2 by
ASQdotCOM - Struts 2.0 should have a workflow component to
compose actions from re-usable steps
49SolutionComposable Actions
- Step 1Write a Java class that implements the
ActionPlugIn interface, to create an action
plug-in. - Step 2Declare (and configure) the action plug-in
that you created in step 1 in the
action-plug-in-config.xml configuration file. - Step 3Add a Struts ltplug-ingt tag to the
struts-config.xml configuration file to get the
action plug-in chain initialized on application
start-up. - Step 4Make sure that there is a ltcontrollergt tag
specified in the struts-config.xml configuration
file, that has its processClass attribute set to
be.ff.web.struts.action.ActionPlugInRequestProcess
or.
50SolutionComposable Actions
- Declaration
- ltaction-plug-in-configgt
- ltaction-plug-ingt ltclassgtActionPlugInlt/classgt
- ltinit-paramsgt
- ltinit-paramsgt
- ltdisabled-forgt /logon
- lt/disabled-forgt
- lt/action-plug-ingt
- ltaction-plug-ingt ltclassgtWorkflowActionPlugInlt/clas
sgt - lt/action-plug-ingt
Java Use public ActionForward execute() throws
ActionPlugInException UserAccount account
(UserAccount) session.getAttribute(accountSessionK
ey) if (account null) return
mapping.findForward("logon") else
return chain.execute(mapping, form, request,
response)
51Re-Use
- There are two possibilities for re-use in Struts,
pages and actions - Re-use of actions is very difficult because
- the granularity of the actions is too high (one
action per page) - The actions cannot be chained together or
segmented - Re-use of pages in struts is very difficult
because - There is no context object tracking location,
etc. - There is no way of overriding a page/form
declaration within a context
52Action Re-use
Action Re-use
53J2EE Integration
- Struts does not provide any out of the box
functionality for J2EE integration (EJBs, JDO,
JDBC, JMS, JavaMail) - Each project/development team must decide ahead
of time on a mechanism to do J2EE integration - Developers must build their own frameworks for
J2EE integration even in very simple applications
54Solution J2EE Integration
- Create Declarative support for long-lived model
objects (beyond forms) - Create Struts J2EE integration (session and
entity beans) using dynamic value objects and
session bean proxies - Create Struts JDO integration
55Solution J2EE Integration
56Events
- Struts provides no mechanism for event based
functionality - Though not strictly required, it is often much
easier to write some function using an event - For example, if you want to run some function
every time the user goes to the edit page, but
the edit page can be reached by 10 different
actions
57Solution Event Subsystem
- Create an Event Multicaster/Controller to manage
event listeners and publish specific events - Most useful events are Navigation, Action, Form
events - Create Action Superclass which fires navigation
and action events - Create Dynamic form superclass which fires form
events
58Solution Event Subsystem
Fire Action Event
Fire Navigate Event
59Content Integration
- Struts provides very little in terms of content
management integration. - If your team uses custom content management
systems, you will have to customize the own
framework - The message framework in Struts is only
acceptable for small to medium applications
60Solution Content Integration
- Customize Message Resources classes to handle
more advanced input - Customize Validator framework to handle more
advanced input - Possible input mechanisms
- Xml files
- Content Management Systems
- DBMS
61Section 3 Conclusion
- While Struts 1.1 provides excellent features for
web applications it may be deficient for
Enterprise class architectures - Large Application Teams may need to create a
custom Struts implementation to accomplish - Contextual Page Handling
- Dynamic Action Branching and page flow
- Composable Actions for Re-Use
- Significant J2EE integration
- Event Handling
- Content Management Integration
62Resources
- Struts website http//jakarta.apache.org/struts
- Struts Action Plug-in Extension 1.0.2
http//www.asqdotcom.be/struts/ - Struts workflow proposal http//jakarta.apache.or
g/struts/proposals/workflow.html - Struts Resources http//jakarta.apache.org/struts
/resources/index.html