This document contains the release notes for Version 1.0-beta-1 of the Struts Framework. The following sections cover New Features and Changes since the Version 0.5 of Struts was made available.
One global new feature to take note of is that Struts 1.0 requires a Java2 (JDK 1.2 or later) platform on which to run.
The following major new features have been added to the
controller
servlet and associated classes
(package
org.apache.struts.action
):
locale
servlet initialization
parameter to
true
, the controller servlet will now calculate
a Locale for this user (based on the Locale returned by
the servlet
container, or by the HTTP headers included with the
request)
and store it in the user's session, unless the application
has stored one there already.
Action
instances now have lifecycle support.
The controller servlet will call
setServlet()
with a
non-null argument when the instance is first created, and
call it with
a
null
argument when the instance is being shut down.
org.apache.struts.actions
) is kicked off with a set of
simple actions that allow on-the-fly changes in the form
bean, forward,
and mapping definitions registered with the controller
servlet. These
actions would normally be configured behind security
constraints to
prevent interference with the operation of your
application but can be
very useful during development.
ActionError
and
ActionErrors
) has been created that allows errors to be
associated with individual fields, and stores parameter
replacement
values along with the messages keys.
ActionForm
interface has been converted to a base class,
with default implementations of some useful functionality.
In addition,
the new class provides two
validate()
methods that take
the current mapping and current request as arguments, in
order to provide
access to more context information than just the
properties of this
particular form bean.
ActionForm
class also provides two
reset()
methods that take the current mapping and current
request as arguments, in order to provide access to more
context
information (particularly important on multi-page forms so
that the form
bean knows which properties to reset). Among other things,
use of the
reset()
methods can prevent problems with checkbox fields
-- simply reset boolean fields to
false
and they will be
set to
true
(during auto-population of the form bean
properties) only if the checkbox was actually checked.
java.io.Serializable
.
Action
class now includes support for "transactional
tokens", so that you can detect cases where the user
submitted a form,
then went back and resubmitted the form again.
The following major new features have been added to the
struts-bean
custom tag library (package
org.apache.struts.taglib.bean
):
<bean:page>
, is available
to expose key items from the page context associated with
the current
page as scripting variables, and as page-scope beans. For
example,
you can use the following sequence to render the server
information
string returned by our servlet context:
<bean:page id="app" property="application"/> <bean:write name="app" property="serverInfo"/>
<bean:struts>
, is available
to expose internal Struts configuration objects (form
bean, forward,
and mapping definitions) as scripting variables and
page-scope beans.
For example, you can use the following sequence to render
the actual
context-relative path of an
ActionForward
object:
<bean:struts id="link" forward="success"/> <bean:write name="link" property="path"/>
name
attribute referring to a JSP bean now also accept an
optional
scope
attribute to define the scope in which to search
for that bean. If not specified, all scopes are searched.
<bean:size>
tag will create a bean that stores
the number of elements of an array, Collection, or Map.
The
struts-html
custom tag library has been created (package
org.apache.struts.taglib.html
), based on the old tags that
were related to HTML form presentation. The following
differences from
the old tags are notable:
options1
tag has been eliminated since Struts is now
based on Java2.
final
modifiers removed, and
private
instance variables
changed to
protected
. This makes it possible to easily
subclass these tags to provide specialized functionality.
<html:link>
tag has been enhanced to support
a new
page
attribute that allows you to use
context-relative URIs in a portable manner.
<html:html>
tag has been created that
renders an HTML
<html>
element with appropriate
lang
and
xml:lang
attributes, based on the
locale stored for the user's session (if there is one).
<rewrite>
tag has been created that
renders a request URI, possibly encoded with a session
identifier,
based on exactly the same rules used by the
<link>
tag that generates hyperlinks. These constants can be
useful when
you are creating JavaScript code that needs to be aware of
Struts
addressing concepts.
options
tag now supports a new
collection
attribute,
which can be used to specify a collection whose beans have
properties
that return the value (to be returned to the server) and
the label (to
be displayed to the user) from a single collection. The
previous
support for processing parallel collections is still
available.
form
tag has been enhanced to look up the name of the
form bean, it's Java class, and the scope in which the
bean should be
created or accessed, from the corresponding action mapping
entry in the
"struts-config.xml" file, if the
name
,
scope
,
and
type
attributes are not specified. This removes the
need to make changes in two places when these values are
changed.
<image>
tag has been added, to create
HTML input tags of type "image".
form
tag has been enhanced to read its configuration from
a corresponding action mapping entry in the
"struts-config.xml" file,
if the
name
,
scope
, and
type
attributes are not specified. It can look up the name of
the
form bean, its Java class, the scope in which the bean
should be
created or accessed, plus the path to which the form
should be
submitted. This removes the need to make changes in two
places when these
values are changed. It works for cases where the
controller servlet is
extension mapped or path mapped.
<html:img>
tag has been added, to render an HTML
<img>
tag.
A new package of Actions and associated classes for handling
file uploads
has been created (package
org.apache.struts.upload
):
webapps/struts-upload.war
).
The following major new features have been added to the utility
classes
library (package
org.apache.struts.util
):
javax.sql.DataSource
interface from the JDBC 2.0 Standard
Extensions API. This implementation may be configured
based on new
extensions to the Struts configuration file DTD, and the
configured
data sources / connection pools are made available to
application
components as a servlet context attribute (i.e. an
application scope
bean).
MessageResources
, which was
ultimately based on
java.util.ResourceBundle
, has been
completely replaced and re-implemented. The primary
features of the
new implementation are:
java.io.Serializable
interface, to better integrate
with application servers that prefer this.
MessageResources
and
MessageResourcesFactory
classes have been abstracted so that you can
easily create your
own implementations that derive their message
strings from resources
other than property files.
PropertyUtils
can now
use a new syntax for indexed and nested properties.
The following major new features have been added to the Struts Example Application :
The following major new documentation updates have been added to Struts:
org.apache.struts.digester
and
org.apache.struts.util
packages.
struts-bean
,
struts-html
,
struts-logic
, and
struts-template
.
struts-blank
, is included as a
quick starting point for new application development.
The following changes and bug fixes to the controller servlet
and
associated classes (package
org.apache.struts.action
) have
occurred:
ActionMapping
interface has been converted to a base
class instead, to reduce the impact of future
enhancements. Anyone who
has extended the
ActionMappingBase
convenience base class
(which has been deprecated) should extend
ActionMapping
instead.
ActionMapping
have been substantially
updated. See the ActionMapping API Documentation for more
information
Action
interface has been converted to a base class
instead, to reduce the impact of future enhancements.
Anyone who has
extended the
ActionBase
convenience base class (which
has been deprecated) should extend
Action
instead.
servlet
argument has been removed from the parameter list for the
perform()
method, because it is now redundant -- the
associated servlet is set via the
setServlet()
method
when the
Action
instance is first created.
Action
instances has been moved
from
ActionMapping
to the controller servlet, so that
instance lifecycle management can be performed. As a side
effect of this
change, if you had two actions that used the same Action
class name,
there will now be only one (shared) instance of the Action
class,
rather than two.
log(String, int)
method that logs the associated message
only if you have configured the debugging detail level for
the servlet to
an equal or higher value.
ActionServlet
, the functionality to populate form bean
parameters from a request, and the functionality to
validate the form
bean's contents, has been separated into two methods that
can be
overridden individually if required.
ActionServlet
functionality to call the
validate()
method of a form bean is skipped if the user
pressed the Cancel key (i.e. the submit button created by
the
<html:cancel>
custom tag), or if the selected
mapping does not define an input form to return control
to.
RequestDispatcher.include()
or
<jsp:include/>
call. Previously, it would mistakenly
use the original request URI, rather than the included
path, to calculate
which action class to execute.
ActionMappings.getUnknown()
method now takes the current
request as an parameter, so that context-sensitive
decisions can be
made.
ActionForward
that
has the
redirect
property set, it now performs URL rewriting
to maintain session state even if cookies are not being
used.
ActionErrors
class now includes a method that will
return an Iterator over the error messages related to a
particular
input field.
The following changes and bug fixes to the Digester module
(package
org.apache.struts.digester
) have occurred:
Digester.resolveEntity()
method has been enhanced
to correctly handle local URIs so that it works with
resources loaded via
Class.getResource()
.
The following changes and bug fixes to the
struts-bean
custom
tag library (package
org.apache.struts.taglib.bean
) have
occurred:
<bean:write>
tag will filter output
for characters sensitive to HTML. You can turn this off by
adding a
filter="false"
attribute.
<bean:include>
in a page that is
part of a session, pass the session identifier along on
the generated
request so that it will be part of the same session.
<bean:define>
tag can now create
beans directly from the
value
attribute, if desired.
<bean:define>
tag now accepts an optional
toScope
attribute, to declare which scope the new bean
should be created in. The default remains
page
scope.
<bean:cookie>
,
<bean:header>
, and
<bean:parameter>
tags, which are used when the
corresponding value is not present in the current request.
The following changes and bug fixes to the
struts-html
custom
tag library (package
org.apache.struts.taglib.html
) have
occurred:
<html:html>
tag now supports a
locale="true"
attribute that requests the same Locale
negotiation (based on the presence of an
Accept-Language
header) that is performed by the controller servlet.
<html:link>
tag now supports the ability to add
a single request parameter (based on a bean property) in
addition to the
ability to add request parameters from a Map.
<html:errors>
tag lets you select only the error
messages related to a particular input field, or all
errors.
<html:password>
tag now optionally redisplays
the previous value of the input field.
<html:multibox>
tag can now
be specified in the body of the tag, as well as via the
value
attribute.
The following changes and bug fixes to the
struts-logic
custom tag library (package
org.apache.struts.taglib.logic
)
have occurred:
<logic:present>
and
<logic:notPresent>
tags now accept a
role
attribute that allows you to detect whether the currently
authenticated
user does, or does not, possess a particular security
role.
The following changes and bug fixes to the
struts-template
custom tag library (package
org.apache.struts.taglib.template
)
have occurred:
<template:put>
tag now accepts a
direct
attribute that causes the content being put to be
rendered directly, rather than being included.
The following changes and bug fixes to the Utilities package
(package
org.apache.struts.util
) have occurred:
PropertyUtils.getPropertyType()
to correctly return
the underlying element type even if there was a
non-indexed property
getter method.
PropertyUtils.setIndexedProperty()
.
BeanUtils
that previously duplicated
functionality that was earlier moved to
PropertyUtils
has been removed.
PropertyUtils.copyProperties()
to skip cases where
the origin bean has a getter method but the destination
bean does not
have a setter method.
BeanUtils.cloneBean()
to create a new instance of
an existing bean, and copy all known properties, even if
the bean class
does not implement
Cloneable
.
BeanUtils
class has been refactored so that it, and
the associated
ConvertUtils
and
PropertyUtils
classes, can easily be used without having to have the
servlet API
classes available on the classpath.
The following changes and bug fixes to the Struts Example
Application
(package
org.apache.struts.example
and the corresponding web
components) have occurred:
reset()
methods defined by the
ActionForm
interface to reset form bean properties to
default values. This is particularly important to make
boolean
properties (represented visually by checkboxes) work
correctly.
PropertyUtils.copyProperties()
method to initially
populate form beans from underlying data objects, and to
update date
objects when a transaction is successfully completed. Note
that using
this approach dramatically lessens an action class's
dependence on the
specific properties of the form bean and corresponding
data object
in many use cases.
autoConnect
boolean property to the Subscription
data object, primarily to illustrate that representing a
boolean
property with a checkbox now works correctly if you set
the property
to
false
in the
reset()
method of your
form beans.