Title: Building Web Applications With The Struts Framework Craig McClanahan Amy Roh Slides: http:www.apache
1Building Web Applications With The Struts
FrameworkCraig McClanahanAmy RohSlides
http//www.apache.org/craigmccOReilly Open
Source ConventionJuly 7 - 11, 2003
2Tutorial Outline
- Technology Backgrounder
- Introduction To Struts
- Our First Struts Application
- Web Application Architecture Decisions
- A More Advanced Struts Application
- Struts and Emerging Technologies
- Information Resources
3TechnologyBackgrounder
4Technology Backgrounder
- Struts is based on a host of foundational
technologies - It behooves web application developers to be
familiar with the basic characteristics of these
technolgoies - World Wide Web (WWW) Standards
- HTTP, HTML, JavaScript
- Java API Standards
- Servlet, JavaServer Pages (JSP)
5Technology Backgrounder HTTP
- Hypertext Transfer Protocol (HTTP) is the
fundamental communications protocol of the World
Wide Web - Simple to implement (client and server)
- Request/response oriented
- Stateless (no client identity across requests)
- HTTP/1.0 TCP connection per request
- HTTP/1.1 Supports persistent connections, for
better throughput
6Technology Backgrounder HTTP
- So, what really happens when you type a URL like
http//localhost8080/index.html into your
browser's location bar? - Your browser sends the following text, with CR/LF
at the end of each line (signified by the ?
symbol) - GET /index.html HTTP/1.1?
- Host localhost8080?
- If-Modified-Since (cache-timestamp)?
- User-Agent (browser-id-string)?
- ?
7Technology Backgrounder HTTP
- And the server returns something like this
- HTTP/1.1 200 OK?
- Last-Modified Fri, 30 May 2003 125638 GMT?
- Content-Type text/html?
- Content-Length xxx?
- Server Apache-Coyote/1.1?
- ?
-
-
- Welcome To My Web Site
-
- ...
8Technology Backgrounder HTTP
- Does the .html extension mean that this
response was from a static HTML page? - Only your server knows for sure -)
- How do redirects work?
- HTTP/1.1 302 Temporary Redirect?
- Location http//foo.bar/baz.html?
- What about BASIC authentication?
- HTTP/1.1 401 Not Authorized?
- WWW-Authenticate Basic realmLog In?
9Technology Backgrounder HTTP
- Significant issues for developers
- HTTP is stateless, so we need a way to tie
requests from the same user together - Servlet API uses cookies or URL rewriting
- Browsers can cache responses per URL
- Server returns Not Modified (304) status
instead of the response content - Usually not what you want for dynamic web
applications
10Technology Backgrounder HTTP
- Significant issues for developers
- What does a URL mean?
- Significant debate in the web architecture
community - As we will see, Struts decouples URLs from the
content they return - Web Applications ! Web Sites
- Browsers have Bookmarks
- Browsers have Back Buttons
11Technology Backgrounder HTML
- HTTP is agnostic to the content type it is
carrying - Defined by the Content-Type header
- Common content types include text/html,
text/xml, image/gif, ... - Official content types are registered with the
Internet Engineering Task Force (IETF) - Hypertext Markup Language (HTML) is very common,
because it is used by many web browsers
12Technology Backgrounder HTML
- Official standards for HTML (as well as other
web-related standards like Cascading Style Sheets
(CSS)) are developed by the World Wide Web
Consortium (W3C) - Current official version of HTML is 4.01
- But many (most!) browsers support non-portable
extensions - Struts only supports standard elements and
attributes
13Technology Backgrounder HTML
- Recent standards activities focused on recasting
HTML into an XML-compatible document type XHTML - Allows pre-processing and post-processing by
XML-compliant tools - Requires more careful editing of source documents
to ensure well-formed and valid content is
produced - Struts supports an option to render XHTML output
instead of HTML
14Technology Backgrounder HTML
- Significant issues for developers
- Browsers support different (and sometimes
incompatible) versions of HTML - You can look at the User-Agent header to make
programmatic decisions - But some browsers can or will lie to you
- Be very careful when you allow users to enter
marked-up HTML into a database, and then render
it as part of your page - Very easy to create cross site scripting
vulnerabilities
15Technology Backgrounder JavaScript
- JavaScript support (in some fashion) is embedded
in almost every popular web browser currently
available - But you cannot count on your users having it
enabled - Original definition came from Netscape
- Supports accessing and manipulating the DOM of
the client browser - Currently standardized as ECMAScript is under the
auspices of ECMA International
16Technology Backgrounder JavaScript
- From the perspective of the server, JavaScript
code is part of the response content ... it is
not special - JavaScript event handlers execute on the client,
rather than the server - Can be embedded in a page, or referenced in a
separate resource - Can be hand coded by the page author, or
generated dynamically by web applications
17Technology Backgrounder JavaScript
- Struts support for JavaScript includes
- Standard HTML event handler attributes (onsubmit,
onmouseover, ...) available on all relevant HTML
tags - Form tag focus attribute uses JavaScript to
initialize the position of the cursor on a newly
rendered form - Validator Framework can optionally generate
client-side JavaScript to implement the same
correctness checks that will be performed on the
server side.
18Technology Backgrounder Java
- No, we're not going to try to learn how to
program in Java here -) - Large numbers of web resources, books, and
magazine articles are available - Instead, we'll look at some particular issues
relevant to web application development
19Technology Backgrounder Java
- Java supports multithreaded applications
- There can be more than one thread of execution
running your code - On a multiprocessor machine, this can be
happening literally at the same time - The JVM maintains a stack containing the local
variables for each thread - Instance variables in the same object instance
are shared across threads - Same for static variables in the same class
20Technology Backgrounder Java
- Java supports a multiple class loader environment
- Class loaders arranged in a parent-child
hierarchy - Request to load a class starts from the top, down
to the loader that loaded the calling class - Class ABC loaded from class loader 1 is not the
same as class ABC loaded from class loader 2 - Even if the bytecodes are identical!
21Technology Backgrounder Servlet API
- Java standard API for writing HTTP-based web
applications - Developer creates a servlet that responds to
individual requests - Single instance of each servlet is created
- Created at startup time or on first request
- Multithreaded calls to doXxx() per request
- Cleaned up at shutdown time
22Technology Backgrounder Servlet API
- public class MyServlet extends HttpServlet
- ...
- public void doGet(HttpServletRequest req,
- HttpServletResponse res) throws ...
- // Set HTTP headers on the response
- res.setContentType(text/html)
- // And write the response content
- PrintWriter writer res.getWriter()
- writer.println() ...
-
- ...
23Technology Backgrounder Servlet API
- Servlets are combined into a web application
- Packaged in a web application archive (WAR) file
- JAR file with particular layout
- Configured using a web application deployment
descriptor (/WEB-INF/web.xml) file - Bound to a context path like /shopping
24Technology Backgrounder Servlet API
- Request URLs are mapped to individual servlets
via (context relative) URL patterns - /foo Exact match
- /foo/ -- Starts with specific string
- .foo Ends with specific extension
- All components of URL available on
HttpServletRequest object via methods
25Technology Backgrounder Servlet API
- Sessions provide a mechanism to work around HTTP
statelessness - Session identifier passed back and forth with
client via cookie or URL rewriting - Session lives on server in between requests
- Programmatic timeout interval between requests
- Container Managed Security supports
authentication and authorization of users - Won't be covered in this tutorial
26Technology Backgrounder Servlet API
- Event Listeners for lifecycle events
- Application creation/shutdown/attributes
- Session creation/shutdown/attributes
- (Servlet 2.4 or later) Request creation/shutdown/a
ttributes - Filters allow composition of processing
pipelines. Examples - Roll your own authentication
- Post process generic XML output with user
specific XSLT transformation
27Technology Backgrounder
- Request Dispatcher supports composition and
delegation - Include Incorporates output from a separate
servlet into a composite result - Similar to server side include in a web server
- Forward Delegates creation of output for this
request to a different servlet - Behaves like a server side go-to
- Client has no clue this happened (URL does not
change in location bar)
28Technology Backgrounder Servlet API
- Significant issues for developers
- Multithreading
- Instance variables should not be used for
per-request state information - Session attributes need to be threadsafe
- Class Loading
- Each web application has its own class loader
- Most containers support shared parent class
loaders - Not all code can be shared!
29Technology Backgrounder Servlet API
- Significant issues for developers
- HTTP requires headers at the beginning of the
response - Container buffers output until committed
- Web application deployment descriptor has element
ordering requirements - Fixed in Servlet 2.4
- In the mean time, easier to use a tool
- Mixing presentation and business logic in a Java
class can be hard to maintain
30Technology Backgrounder JavaServer Pages (JSP)
- Servlets embed dynamic logic and markup
generation in Java - JavaServer Pages embed dynamic logic in static
markup (typically HTML) - Application server converts each page into a
servlet and compiles it - Dynamic logic embedded with scriptlets,
expressions, or custom actions (tags)
31Technology Backgrounder JSP
-
-
-
- Hello, World
-
- Hello !
- Today's date is
-
-
32Technology Backgrounder JSP
- Scriptlets let you embed Java code in your JSP
pages - That can be good ... full power of Java
- That can be bad ... O-O syntax, wordy
- Custom Actions (custom tags) let Java developers
create reusable classes for - Interacting with business logic
- Creating markup dynamically
33Technology Backgrounder JSP
- Standard Actions provided for common
requirements -
-
-
- JSP Standard Tag Library (JSTL) covers other
basic needs (iteration, conditionals, XML
processing, i18n, ...)
34Technology Backgrounder JSP
- Significant issues for developers
- Since a JSP is a servlet, you can leverage all of
the capabilities of the Servlet API - Since a JSP is a servlet, all of the servlet
issues continue to apply - In particular, mixing presentation and business
logic in a JSP can be hard to maintain
35IntroductionTo Struts
36The Origin Of Struts
- Like many open source projects, Struts started
with me scratching my own itch - Take a US-centric application to Europe ...
- In multiple languages (4 initially) ...
- And make it available on the web ...
- I was familiar with Java and open source
- Apache JServ and Tomcat containers
- But there was no good model for a web application
architecture available
37The Origin Of Struts
- The JSP 0.91 Specification described two
fundamental approaches - Model 1 A resource (such as a JSP page) is
responsible for both creating the markup for a
form, and for processing the resulting submit - Model 2 A resource (such as a JSP page) is
responsible solely for creating the markup
processing the submit is dispatched to a separate
resource
38The Origin Of Struts
- The second approach sounded better
- Resources for creating markup and performing
database updates are separated - So they can be built by different people
- So they can be built with different technologies
- So, I built a home grown architecture based on
the Model-View-Controller paradigm popular in
client-server applications
39Model-View-Controller (MVC)
- Model The persistent data (typically in a
database) and business logic functionality - View The user interface (typically HTML forms
in a web application) - Controller Management software to dispatch form
submits to the corresponding business logic, and
trigger the display of the appropriate next page
40MVC As Implemented In Struts
Controller
Business Logic
Browser
Model Data
View
41Struts Features Model Tier
- Struts includes only minimal infrastructure for
the model tier - A basic implementation of javax.sql.DataSource is
included ... - But you can integrate any desired approach
42Struts Features View Tier
- Form Beans
- Represent the server side state of the input
fields on an HTML form - Contains hooks for resetting fields to default
values (needed for checkboxes) and input field
validation - DynaActionForm means you do not have to create
new JavaBeans yourself
43Struts Features View Tier
- Validation Framework
- Abstract input validation rules into separate XML
document - Extensible for custom field checking
- Optionally generates client-side JavaScript
- Always checks on server side
- Integrated with standard ActionForm beans and
DynaActionForm beans
44Struts Features View Tier
- (JSP) Custom Tag Libraries
- Bean General purpose bean and property
manipulation - Html Dynamic HTML-based user interfaces
(including input forms) - Logic Conditionals and iteration
- Nested Versions of other tags that access
nested JavaBean hierarchies easily - Tiles Layout management (next page)
45Struts Features View Tier
- (JSP) Tiles Framework
- Supports templating for common look and feel of
all pages in a web app - Tile definitions created in JSP page or in
external XML document - Definitions can extend base definitions
- Advanced techniques for dynamically passing
information to tiles
46Struts Features Controller Tier
- Configuration Document Defines Behavior
- Action URLs mapped to Actions
- Data sources
- Exception handlers
- Form beans
- Forwarding URLs mapped to Pages
- Message Resources for i18n
- PlugIns for Lifecycle Management
- One or more documents allowed
47Struts Features Controller Tier
- Request Processing Lifecycle
- Extract action mapping path
- Select locale (if necessary)
- Select action mapping to utilize
- Perform role-based access checks
- Server-side validation (if requested)
- Invoke application Action
- Forward based on application outcome
- Highly customizable and extendable
48Struts Features Controller Tier
- Sub-Application Modules
- Logically divide single web application into
multiple Struts mini-applications - Session state shared across all modules
- Standard Action Implementations
- Forward or include other URLs
- Dispatch to one of several methods in an Action
class - Switch from one sub-application module to another
49Struts Features Miscellaneous
- Jakarta Commons Libraries
- BeanUtils Access bean properties dynamically,
support DynaBeans - Collections Extensions to Java2 Collections
Classes (java.util) - Digester Parse XML documents and configuration
files - FileUpload Support
- Lang Extensions to core JDK classes (java.lang)
50Struts Features Miscellaneous
- Jakarta Commons Libraries
- Logging Abstract logging layer over Log4J, JDK
1.4 logging, or others - Validator Validation framework that can be used
in the business logic tier - Jakarta-ORO regular expression processing
51Struts Features Miscellaneous
- Extensive documentation and Javadocs
- Wide variety of third party resources
- Example web applications
- Blank starter application
- Simple basic example
- Exercise individual tags
- General and specific documentation on all Struts
features
52Our FirstStrutsApplication
53The Canonical Struts Example
- Delivered as webapps/struts-example.war in a
Struts distribution - Can be dropped in to any Servlet 2.2 / JSP 1.1
(or later) container to verify proper support for
Struts - Simulates (the beginnings of) a web application
acting as a proxy for one or more IMAP or POP3
mail subscriptions - Let's take a look at its the app in action ...
54The Configuration Files
- web.xml Webapp deployment descriptor
- ActionServlet is the controller
- Multiple configuration files supported
- Typically loaded at startup time
- Mapped to extension pattern (.do) or path prefix
pattern (/do/) - Identifies the application Welcome File
- (JSP 1.1 only) Must declare tag library
descriptors
55The Configuration Files
- struts-config.xml Struts configuration
- Form beans (one dynamic, one standard)
- Global exceptions (none in this app) define
handlers for exceptions of particular types - Global forwards provide logical names for
physical pages - Action mappings map URLs to Actions
- Can nest local and
definitions
56The Configuration Files
- struts-config.xml Struts configuration
- Controller has global configuration settings
- Message resources elements load sets of localized
message text for i18n - Plug ins provide lifecycle (webapp start and
stop) support for extensions - struts-config-registration.xml Illustrates that
you can use multiple config files - struts-config_1_1.dtd Documents content of
Struts configuration file elements
57Walk Through Logon Processing
- Start on /index.jsp, second hyperlink
-
-
-
- Generated source is localized
-
- Log on to the MailReader Demo ...
- Automatic URL encoding supplied also
- Direct link to JSP page is unusual
- Useful only in no setup situations
58Walk Through Logon Processing
- The /logon.jsp page is displayed
- Contains a custom form tag
-
- focususername onsubmit...
- Action attribute matches configured
element - Focus positions cursor via JavaScript
- Onsubmit ties in to validation processing
- Two input fields plus submit/reset buttons
- Tags generate smart HTML
59Walk Through Logon Processing
- Submits to /struts-example/logon.do
- Invokes ActionServlet processing
- Selects the correct element
-
- typeorg.apache....LogonAction
- namelogonForm
- scopesession
- inputlogon/
60Walk Through Logon Processing
- Instantiates logonForm bean if needed, per form
bean definition -
- typeorg.apache....DynaValidatorForm
-
- typejava.lang.String/
-
- typejava.lang.String/
-
61Walk Through Logon Processing
- Server-side validation is performed based on
configured validation rules -
-
- dependsrequired,minlength,maxlength ...
- ...
-
- In this case, we used client-side validation as
well, via generated JavaScript - You should never trust client-side validations to
be enough ...
62Walk Through Logon Processing
- If validations fail, control goes to the logon
forward -
- typeorg.apache....LogonAction
- namelogonForm
- scopesession
- inputlogon/
- Which was defined to point at the logon page in a
global forward definition -
63Walk Through Logon Processing
- If validation succeeds, the execute() method of
our configured Action class is invoked (Command
Pattern) - public class LogonAction extends Action
- public ActionForward execute
- (ActionMapping mapping, ActionForm form,
- HttpServletRequest request,
- HttpServletResponse response)
- throws Exception ...
-
64Walk Through Logon Processing
- The action checks the username and password
against the user database ... - On unsuccessful match, stores an error message
and returns to the input page - return (mapping.getInputForward())
- On successful match, logs user in and indicates
success - return (mapping.findForward(success))
- Which transfers to the main menu page
65But What About Prepopulation?
- Often, you need to pre-populate fields to be
displayed on a page - The Edit Registration option illustrates a very
typical Struts design pattern - Setup action populates beans (including the
form bean), and forwards to ... - Page that displays the populated form, and
submits to ... - Process action that updates the database based
on the new user input values
66Walk Through Edit Registration
- Let's walk through the Edit Registration
processing of the example application - A little faster, now that we've got the hang of
how Struts handles requests - We start on the main menu (first link)
-
-
67Walk Through Edit Registration
- The /editRegistration action declares a form
bean, but with no validation -
- type...EditRegistrationAction
- nameregistrationForm
- scoperequest
- validatefalse/
- So, Struts precreates an empty form bean, but
does not trigger validation on it
68Walk Through Edit Registration
- The EditRegistrationAction's execute() method
then - Ensures that there is a logged on user
- Copies the user's info to the form bean
- Sets a transaction token to disallow double
submits (saveToken()) - Forwards to the success logical forward
- For this action, we have a local override of
success that selects /registration.jsp instead
69Walk Through Edit Registration
- The /registration.jsp page displays the form
values, already filled out because of the setup
Action's activity - The form submission goes (after validation is
completed) to the /saveRegistration action, which
... - Updates the database
- Goes back to the main menu again
- You will see this three-step pattern over and
over again in Struts-based applications
70Example Application Summary
- We've seen the basic organization and features
that Struts provides - Struts lives up to its promise to separate the
concerns of the presentation logic and the
business logic - But what about a bigger application? How do I
organize things when I've got 50 pages instead of
5?
71Next Steps
- Examine the architectural decisions required to
design and build a web application - Examine how these decisions were done in a more
advanced Struts-based application - But first ... let's take a quick break
72(No Transcript)
73Web ApplicationArchitecture Decisions
74Overall Architecture Decisions
- Let's start by assuming we are going to use
Struts to develop a fairly large application - Good choice -)
- Our required decisions follow the separations of
the MVC paradigm - Model Related Decisions
- Technology for persistence tier
- Technology for business logic
- Transporting data to presentation tier
75Overall Architecture Decisions
- View Related Decisions
- Technology for markup generation
- Layout management strategy
- Form bean strategy
- Input validation strategy
- Localization strategy
- Controller Related Decisions
- Mapping logical names to physical resources
- Responsibility split between Actions and Business
Logic
76Development Process Decisions
- Maximize opportunities for concurrent development
across tiers - Identify required cross-tier knowledge transfers
- Strive to hide implementation details
- Application architect should own configuration
file management - Struts-config.xml tends to be a clearinghouse for
cross-tier communication - Can subdivide on functional lines if needed
77Persistence Tier Technology
- In many cases, this decision will have already
been made for you - Creating new web-based interface to existing data
or functionality - In many cases, there will be more than once
answer needed in the same app - Tables in existing relational databases
- User information in a directory server
- Connector to legacy applications
78Persistence Tier Options
- Relational Database (RDBMS)
- Very common choice
- Rows and columns paradigm is well understood
- Mature, high performance products available
- Programmatic access, directly (JDBC) or
indirectly (EJB, O-R mapping tiers, ...) - Relational organization often needs to be adapted
to O-O design patterns
79Persistence Tier Options
- Object-Oriented Database (OODBMS)
- Persistent data directly reflects object oriented
relationships - Some databases implement this directly
- Others define and/or generate a mapping of
objects onto RDBMS tables - Relatively newer, less mature
80Persistence Tier Options
- Flat Files
- Best for sequential-only access
- Can utilize text or binary data formats
- Text formats tend to be more flexible
- Binary formats tend to be more compact
- Common text-based formats
- One row per line with comma-separated columns
(often called CSV) - Extensible Markup Language (XML)
- Nice for hierarchical data
- Becoming popular for inteoperability
81Persistence Tier Options
- Integration Connectors
- Often used to connect with legacy applications
- Typically implemented as a network based protocol
accessing a remote application or service - Web Services is about standarizing integration
using XML data contents, described by WSDL
metadata
82Persistence Tier Decision Goals
- Define an API abstraction for use by business
logic developers - Independent of web tier, so can be reusable
- Presented in O-O terms for familiarity
- Functional content driven by business logic
requirements
83Persistence Tier Decision Goals
- Insulate business logic developers from changes
in underlying environment - Database Administrator splits tables
- Data source changes from flatfile to RDBMS or web
service or EJB - Data transport APIs for the presentation tier may
be defined here - Or in the business logic tier
84Persistence Tier Decision Goals
- Support transactional capabilities of most
persistence tier technologies - Begin ... Process ... Commit/Rollback
- Supports all or nothing changes to avoid
inconsistent state being stored - Implementation details hidden inside defined APIs
85Persistence Tier Decision Goals
- Support resource pooling to conserve scarce
resources - Connections to resources often scarce
- Allocating connection per user would limit
scalability - Implementation details hidden inside defined APIs
86Business Logic Technology
- The functional behavior of your application
- Add new customer ABC
- Transfer X from acct 123 to acct 456
- Submit purchase order 789
- Typically modelled as an individual Java method
per use case - Enables reuse across apps
- Improves unit testability
87Business Logic Technology
- Should operate on persistence tier API
abstractions, not directly on databases - Insulated from changes in underlying persistence
tier environment - Allows business logic developers to focus on
business problems, not database problems - Should be independent of presentation tier
considerations - Data is locale-independent objects
88Business Logic Technology
- Business logic can be stateful or stateless
- Stateful logic requires multiple interactions
with the user to complete a single business
transaction - Stateless logic can be done in a single call
- Can sometimes model stateful logic as stateless
if you use the persistence tier to maintain the
state for you - Business logic can be implemented in JavaBeans or
EJB session beans
89Business Logic Decision Goals
- Define an API abstraction for use by presentation
logic developers - Independent of web tier, so can be reusable
- Presented as method per use case, with imperative
names - Functional content driven by business logic
requirements - Data transport APIs for the presentation tier may
be defined here - Or in the persistence tier
90Data Transport Strategy
- Presentation tier will require access to dynamic
data to build user interfaces - Dynamic data may originate in
- Persistence tier
- Business logic tier
- Yet, we still want to insulate presentation tier
developers from the underlying details - The usual approach is to use the Data Transfer
Object (nee Value Object) pattern
91Data Transport Strategy
- Typical Java implementation of a DTO is a simple
JavaBean with only properties - Properties are still native object types (to
avoid ties to presentation tier) - Objects are light weight and Serializable
- Supports type safety and compile-time checks on
property getters and setters - Tedious to create and maintain without tools
support
92Data Transport Strategy
- A less tedious approach is to use a java.util.Map
to contain the values to be transported - Objects are light weight and Serializable
- Avoids the need to create and maintain JavaBean
classes for each DTO - Loses type safety checks on property types
- Compiler cannot catch errors like typos in
property names for you
93Data Transport Strategy
- Struts (because it includes commons-beanutils)
supports DynaBeans as a hybrid between these
approaches - Properties (name and type) belonging to a
DynaBean can be configured programmatically - Objects are light weight and Serializable
- Property getters and setters are typesafe, but
name typos still not caught - Interoperates with Struts presentation tags
94Data Transport Decision Goals
- Consider tradeoffs of using JavaBeans versus more
generic options - Maintain independence of presentation tier
considerations (date formats, etc.) - Avoid use of EJB entity beans directly as data
transport objects - Potential network request on each property
getter, versus once to retrieve entire DTO
95Markup Generation Technology
- Decision starts with a description of the client
runtime environment. Typically - Standard browser (usually HTML)
- With or without client-side JavaScript
- Standard browser with plugins (Macromedia Flash,
Adobe Acrobat, SVG Viewer, Java Applets, ...) - Rich client with programmatic capabilities
(JavaWeb Start, client-server GUI, ...)
96Markup Generation Technology
- Based on this, decide where actual markup will be
generated - Server Side Markup composed by server and
displayed by the client (possibly with embedded
scripting) - Typical for HTML-based web apps
- Client Side Server sends a high level
description of the data to be presented, but
client performs layout - Flash, SVG Viewer, Xforms, ...
97Markup Generation Technology
- Server side content can be dynamically generated
via a number of technologies - Programmatic execution of a servlet
- JavaServer Pages (JSP)
- Alternative templating solutions (Velocity,
FreeMarker, ...) - Serialization of XML document objects
- Struts has extra support for JSPs used to render
HTML on the server side, but can be used with
other alternatives as well
98Layout Management Strategy
- High quality user interfaces feature consistent
look and feel across the entire application - Traditional approach in web application design is
cut and paste of common design elements across
all pages - Tedious and error prone
- Makes LF remodels difficult
99Layout Management Strategy
- Most markup generation technologies support
composition of multiple elements - JSP and
- Requires overall layout (i.e. the outermost
) to be present on each page - Limits ability to adjust the overall layout
dynamically (say, based on user preferences)
100Layout Management Strategy
- Struts supports the Tiles Framework for advanced
management of look and feel issues - Pages are assembled from a base layout that is
separate from the actual pages - Layout includes markers to include individual
tiles by composition - Individual tiles responsible for rendering only
their individual portion of the overall content
101Layout Management Strategy
- Tiles Framework supports many advanced features
as well - Layouts can be defined in configuration files,
individual JSP pages, or programatically - Layouts can extend other layouts similar to the
way Java subclasses extend superclasses - Behavior of Tiles can be customized by passing
attributes in a Tiles context.
102Form Beans Strategy
- Users of interactive computer applications have
been trained to expect common behaviors - In particular, users expect the following when
they make an error - A suitable error message will be shown
- The previous (incorrect) input values will be
remembered, so the user need only correct their
errors
103Form Beans Strategy
- Aspects of HTTP and HTML make it difficult to
meet this expectation - HTML input fields are strings, even for data
types that might not be (date, int, ...) - HTTP is stateless, and provides no facilities for
remembering the previous values when a page is
redisplayed - To address this need, Struts defines an API for
form beans (more formally, org.apache.struts.actio
n.ActionForm)
104Form Beans Strategy
- A form bean is a component of the presentation
tier, and has two responsibilities - Represent server-side state of all the input
fields on a form (even if the input data is
syntactically or semantically invalid) - Serve as a data transfer object (DTO) from the
presentation tier to the business logic tier (via
a Struts Action)
105Form Beans Strategy
- Two general implementation strategies are
available - Subclass ActionForm and add properties for each
input field - Leverage Struts support for DynaActionForms, and
define the properties in the Struts configuration
file - Form bean instances are created as needed,
typically in - Request scope
- Session scope
106Form Beans Recommendations
- Unless you have particular needs, use dynamic
action forms - Simpler to manage and maintain
- Do not include business logic directly in your
form bean - Data conversions belong in an Action
- Business logic belongs in separate classes that
are part of the business logic tier
107Form Beans Recommendations
- Declare the data type of all input field
properties as Strings - Exception Checkboxes should be backed by a
boolean property - Reason Consider what happens if you have a
field of type int and the user types 1a3
instead of 123 - User expects validation error message and
redisplay of 1a3 so it can be fixed - User gets a runtime error because of the failed
String-int conversion
108Input Validation Strategy
- Robust applications will never allow incorrect
values to be processed by the business logic
tier, or stored in the persistence tier - Each tier should protect itself from invalid
input from client tiers - Business logic might thrown IllegalArgumentExcepti
on - Persistence tier might throw SQLException because
a database trigger detected a problem
109Input Validation Strategy
- Correctness criteria come from multiple tiers of
an application - Presentation tier date and number formats
- Business logic tier semantic requirements
(minimum six characters in a password, email
address is required) - Presentation tier unique key and foreign key
constraints (that username belongs to someone
else)
110Input Validation Strategy
- High quality user interfaces perform input
checking as close to the user as possible - Per-field instead of per-form is typical
- In web applications, often implemented via client
side JavaScript - But you cannot trust clientside JavaScript to do
everything for you - It might be turned off
- It might be bypassed by a client application
- Cannot check 100 of requirements
111Input Validation Strategy
- Struts offers the Validation Framework to manage
combining correctness checks from all tiers into
a configuration file - Implemented rules are configurable (minimum of
characters) - Set of available rules is extensible
- Correctness checks are triggered automatically
where needed - By form bean name
- By action path
112Input Validation Strategy
- Correctness checks always performed on the server
side - Exception normally disabled for setup actions
- Validation rules can optionally cause client side
JavaScript to be generated that will perform
checks before the form is submitted - Improves user experience to catch these without a
round trip to the server
113Localization Strategy
- Providing a web application in multiple languages
is becoming more common in a global economy - Even if you don't think you need to support
localization, you should do it anyway - You might be wrong -)
- Mechanics of implementing this allow you to share
things like prompt strings and button labels,
even in a single language
114Localization Strategy
- Struts supports localization at all levels
- tag looks up localized text from
resource bundles - Validation error messages are based on keys to
look up localized text, with parametric
replacement - Can interoperate with JSTL for localized
formatting - Message resources can be used programmatically
(localized log messages)
115Logical To Physical Mapping
- Throughout our discussion on decisions, we have
seen a need to isolate developers in one tier
from implementation details in another tier - Maintaining isolation minimizes the impact of
changes inside one tier - Struts provides multiple layers of support for
this by mappings defined in the Struts
configuration file
116Logical To Physical Mapping
- Isolation is based on mapping a logical name for
a resource to the physical implementation of that
resource - Action context-relative URL to Action class
- Form bean name to implementation class
- Exception to handler class
- Forward alias to context-relative URL
- Message resources bundle to implementation
117Logical To Physical Mapping
- That being said, it is useful to define naming
conventions that tie the various Struts features
for a particular page together. - We will see how this was done in the Advanced
application example, soon
118Actions and Business Logic
- Action classes are invoked by the Struts
controller based on the request URL - Command Pattern
- It is tempting to place business logic directly
into Actions - Common in smaller scale, simpler applications
- But this ties business logic to web APIs
- Yes, struts-example is guilty of this -)
119Actions and Business Logic
- Consider Actions part of the controller, not part
of the model - Extract incoming data from form bean
- Convert as necessary into DTOs defined by
business logic tier - Adapter Pattern
- Delegate processing to Business Logic class's
appropriate business method - Make DTOs needed by next page available
- Forward control to the next page
120A More AdvancedStruts Application
121Da Nooz Example Application
- Even before blogging became popular ... Rich Site
Summary (RSS) was a popular XML-based data format
for syndication - This application supports self registration and
personal management of one or more RSS newsfeeds - The RSS newsfeeds themselves are available in
multiple formats - The RSS community is fairly fractured
122Da Nooz Example Application
- Based on Struts 1.1
- Utilizes advanced features like the Tiles and
Validator Frameworks - Implements many best practices for web
applications (with or without Struts) - Illustrates specific architectural choices
- Not by any means the only reasonable ones
- Will be open sourced (probably at
http//java.net) in the near future
123Model Tier Decisions
- Persistence Choices
- Business Logic Choices
- Data Transport Object (DTO) Choices
124Persistence Choices
- Original requirement for this demo included
supporting multiple choices - Java Data Objects (JDO)
- Relational Database (JDBC)
- Flat File (Xml)
- Entity Beans (EJB) not done yet
- Designed persistence tier API to reflect the
natural object hierarchy - User Channel Item
125Persistence Basic Decisions
- Employ Data Access Object (DAO) pattern
- Support transactional state inside DAO
- JavaBeans oriented API to express characteristics
of business entities - Object oriented API to express relationships
between business entities
126PersistenceImplementation Independence
- JavaBeans style interfaces for each entity
- User (nooz.business.User)
- Channel (nooz.business.Channel)
- Item (nooz.business.Item)
- Specific implementations of these interfaces
depend on persistence strategy - Business logic programmed in terms of
interfaces, not implementations - DAO interface (nooz.business.DAO)
127PersistenceDAO Interface
- Transaction Lifecycle Methods
- begin(), close(), commit(), isActive(),
isClosed(), rollback() - Top Level Application Methods
- createUser(), findUser(), findUsers()
- Is it reasonable to separate these concepts?
- Absolutely!
- Tradeoffs always exist
128PersistenceDAOFactory Interface
- In a web environment, it is important to minimize
the amount of time resources are reserved for a
specific user - Holding precious resources across requests is not
a scalable strategy - Connection pools are the usual mechanism for
dealing with this issue - But acquiring and releasing connections from a
pool can be error prone - Answer provide higher level management
129PersistenceDAOFactory Interface
- From an API perspective, very simple
- public DAO getDAO()
- Implementation perspective very useful
- Provide DAO instances for short lived (typically
single transaction) requirements - Business logic using DAO does not have to worry
about error conditions causing resource leakage - Allocated resources freed when DAO instance is
finished
130PersistenceDAOFactory Selection
- In the Da Nooz application, DAOFactory
implementation selection is a configuration
option - Application assember picks a listener to run at
startup time - Listener makes an implementation available as a
servlet context attribute - Application uses generic DAO interface
- Implementation selection can be deferred to
container configuration time
131PersistenceDAOFactory Operation
- DAOFactory implementation is a servlet context
attribute - For each request, a Filter asks DAOFactory for a
DAO for this request - The Filter does not know or care about the actual
DAOFactory implemetnation! - The Filter cleans up (by closing the DAO), even
if the application throws an exception
132Persistence JDBC Implementation
- JdbcDAOFactory hands out DAOs
- Requires a javax.sql.DataSource to handle
connection pooling - Example code uses a JNDI resource for this
- JdbcDAO instance per request
- Connection not allocated until begin() is called
(if request doesn't need one) - Connection returned to pool (if used) when
close() is called (by DAOFilter in a web
application environment)
133Persistence JDBC Implementation
- JdbcHandler Programming queries directly with
JDBC is tedious - Get connection, get statement, get result set,
process each row, close all objects - JdbcDAO offers an easy-to-use query() method to
hide all this complexity - Takes SELECT statement, parameters, and
JdbcHandler instance - Handler called once per selected row
- Hollywood Principle -- Don't call us, we'll call
you
134Persistence JDBC Implementation
- JdbcUser, JdbcChannel, JdbcItem
- Implementation specific persistent objects
- findXxx() contains embedded SQL for SELECT
- remove() contains embedded SQL for DELETE
- save() contains embedded SQL for INSERT or UPDATE
- For database independence, some people abstract
SQL statements to properties file
135PersistenceDecision Results
- Persistence tier supplies a persistence
independent API to business logic tier - Persistence tier is independent of view tier
implementation technology - No ties to Struts Framework APIs!
- Changes to persistence implementation details
hidden inside an abstract API - Business tier is mostly independent of
persistence tier implementation decisions
136Business Logic Choices
- Business logic for Da Nooz is very simple
- Encapsulated as methods on a single class
(nooz.business.logic.Logic) - Each method accepts parameters
- DAO for the current request
- Primary keys (as necessary)
- DTO containing name/value pairs
137Data Transfer Object Choices
- Persistence layer exposes User, Channel, and
Item as abstractions of the underlying persistent
data - Business logic expects java.util.Map parameters
for name/value pairs - Avoids linkage to Struts APIs that would lock it
to web app use only - Could have used DynaBean directly
- BeanUtils.copyProperties() useful for bulk
transfer of name/value pairs w/conversion
138View Tier Decisions
- Technology for markup generation
- Layout management strategy
- Form bean strategy
- Input validation strategy
- Localization strategy
139View Tier Markup Generation
- Chose to use JavaServer Pages
- Popular, well understood, widely deployed
- Struts tag libraries support this platform
- JSP Standard Tag Library (JSTL)
- Used in RSS rendering for access to EL
- Struts offers a struts-el tag library that
supports EL evaluation on JSP 1.2 containers - JSP 2.0 will support EL evaluation everywhere
140View Tier XML Markup
- Da Nooz normally renders HTML for the user's
management activities - It also has facilities to directly create RSS
feeds directly, in multiple formats - This is done using a JSP page as a template
- /rss/version-0_91.jsp
- /rss/version-1_0.jsp
- Templates pull data with JSTL tags
141View Tier Layout Management
- Chose to use Tiles Framework
- page/layout/basic.jsp
-
-
- value/tiles/header.jsp/
-
- value/tiles/footer.jsp/
-
- value/tiles/blank-menu.jsp/
-
- value/tiles/blank-body.jsp/
142View Tier Layout Management
- Actual formatting is in /layout/basic.jsp
-
-
-
-
-
-
-
-
-
-
-
-
143View Tier Layout Management
- Tiles can extend previous definitions
- extends.layout.basic
-
- value/tiles/loggedon-menu.jsp/
-
- extends.layout.loggedon
-
-
- value/pages/menu.jsp/
144View Tier Layout Management
- Individual pages (/pages/menu.jsp) provide only
the content for their til