1
STRUTS 2
1
Ref. & doc.
................................
................................
................................
................................
...................
3
2
Setting up
................................
................................
................................
................................
.....................
3
2.1
Jar dependencies
................................
................................
................................
................................
....
3
2.1.1
Required
................................
................................
................................
................................
........
3
2.1.2
Optional
................................
................................
................................
................................
.........
6
2.1.3
Other interesting utilites (no
n struts)
................................
................................
................................
6
2.2
When adding/touching the jar config
................................
................................
................................
.......
7
3
Configuring struts
................................
................................
................................
................................
..........
7
3.1
Configuring the framework
................................
................................
................................
.....................
7
3.1.1
Via file struts.properties
................................
................................
................................
..................
7
3.1.2
Via file web.xml and tag <init
-
param>
................................
................................
.............................
8
3.1.3
Via file struts.xml and tag <constant>
................................
................................
..............................
8
3.2
Struts.xml
................................
................................
................................
................................
..............
8
3.
2.1
Doc :
................................
................................
................................
................................
..............
8
3.2.2
Example
................................
................................
................................
................................
.........
8
3.2.3
DTD
................................
................................
................................
................................
..............
9
3.2.4
constant names
[configuring struts, configuration]
................................
................................
.........
9
3.2.5
Package, namespace
................................
................................
................................
.....................
10
3.2.6
Interceptors
................................
................................
................................
................................
..
10
3.2.7
Actions
................................
................................
................................
................................
........
10
3.2.8
Results
................................
................................
................................
................................
.........
11
3.2.9
Global results
................................
................................
................................
...............................
12
3.2.10
Global exception mappings
................................
................................
................................
...........
12
3.2.11
struts.xml and the value stack
................................
................................
................................
........
12
3.2.12
Context scoped objects
................................
................................
................................
..................
13
3.2.13
Splitting struts.xml in several files
................................
................................
................................
.
13
4
Interceptors & Interceptor stacks
................................
................................
................................
..................
14
4.1
Doc
................................
................................
................................
................................
.....................
14
4.2
Interceptor, Interceptor stack
................................
................................
................................
................
14
4.2.1
Ready
-
to
-
use stacks
................................
................................
................................
......................
15
4.2.2
Defining a stack of one’s own:
................................
................................
................................
......
15
4.2.3
Other way of extending an interceptor stack : directly in definition of action
................................
...
16
4.2.4
Interceptor params
................................
................................
................................
........................
16
4.3
Interceptors : detail
................................
................................
................................
..............................
16
4.3.1
actionMappingParams + param
s : Mapping the Http request parameters to Action class properties
...
16
4.3.2
Servlet Config Interceptor [session, sessionAware]
................................
................................
.........
22
4.3.3
chain
................................
................................
................................
................................
............
22
4.3.4
conversionError
................................
................................
................................
............................
22
4.3.5
validation
................................
................................
................................
................................
.....
23
4
.3.6
prepare
................................
................................
................................
................................
.........
23
4.3.7
debugging
................................
................................
................................
................................
....
23
4.3.8
execAndWait
................................
................................
................................
...............................
23
4.3.9
ex
ception
................................
................................
................................
................................
.....
24
4.4
Writing one’s own interceptors
................................
................................
................................
.............
26
5
Flow approach (from the HTTP request to the Struts Action)
................................
................................
.........
26
5.1
Receiving the request parameters
................................
................................
................................
..........
26
5.1.1
Parameter interceptor
................................
................................
................................
....................
26
5.1.2
Co
nversion
................................
................................
................................
................................
...
26
5.1.3
From within the Struts2 action
................................
................................
................................
.......
26
5.2
Validating the parameters
................................
................................
................................
.....................
26
5.2.1
General
................................
................................
................................
................................
........
26
5.2.2
Validation occurs after params are set
-
potential security problems
................................
.................
27
5.2.3
Zero
-
l
ength input
................................
................................
................................
..........................
28
5.2.4
Validation with xml validation files
................................
................................
...............................
28
5.3
Passing on the data: linking the action to the domain model
................................
................................
....
32
5.3.1
actionMappingParams and type conversion
................................
................................
....................
32
5.3.2
Exposing the model object
................................
................................
................................
............
33
5.3.3
Using the model
-
driven mechanism
................................
................................
...............................
34
5.3.4
ModelDriven vs ordinarily exposed model
................................
................................
.....................
34
5.3.5
Security is
sues
................................
................................
................................
..............................
34
2
5.4
Processing
................................
................................
................................
................................
...........
35
5.4.1
Execute()
................................
................................
................................
................................
.....
35
5.5
Rendering the r
esult: the web page
................................
................................
................................
........
35
5.5.1
Contexts/Scopes
................................
................................
................................
...........................
35
5.5.2
Choosing the html template language: JSP, Freemarker, Velocity…
................................
................
35
5.5.3
Struts tags
................................
................................
................................
................................
....
35
5.5.4
Form errors, form feedback
................................
................................
................................
...........
53
5.5.5
Ognl
................................
................................
................................
................................
............
54
5.5.6
Tags layout
................................
................................
................................
................................
..
59
5.5.7
Custom tags, custom themes, components
................................
................................
......................
65
5.5.8
JSP
................................
................................
................................
................................
..............
67
5.6
Exception and error management
................................
................................
................................
..........
68
5.6.1
Action class:
................................
................................
................................
................................
.
68
5.6.2
Exceptions arising on the html rendering side (ognl) (jsp)
................................
...............................
70
6
Further inside the Struts2 action
................................
................................
................................
...................
71
6.1
th
e Value Stack
................................
................................
................................
................................
....
71
6.2
Context, invocation… the underlying stuff
................................
................................
............................
72
6.2.1
Action context
................................
................................
................................
..............................
72
6.2.2
Getting/setting the session
................................
................................
................................
.............
72
7
Around (change this title)
................................
................................
................................
.............................
73
7.1
Cookies
................................
................................
................................
................................
...............
73
7.1.1
receive cookies in an action
................................
................................
................................
...........
73
7.1.2
add cookies to a HTTP response in an action class.
................................
................................
.........
74
7.2
Localization [i18n]
................................
................................
................................
...............................
74
7.3
Getting text from message resource [Internationalisation, i18n, labels, properties files]
............................
74
7.3.1
Tag <s:text name="">
................................
................................
................................
...................
74
7.3.2
Function getText()
................................
................................
................................
........................
74
7.3.3
Message resources
................................
................................
................................
........................
75
8
Organisation of a project
................................
................................
................................
..............................
77
9
Working with Eclipse
................................
................................
................................
................................
..
78
10
Working with Spring
................................
................................
................................
...............................
78
10.1
Setting up
................................
................................
................................
................................
............
78
10.2
Getting the logger if not in a class instantiated by Spring:
................................
................................
.......
78
10.3
Access beans created by Spring from anywhere
................................
................................
.....................
79
11
Cookbook
................................
................................
................................
................................
...............
79
11.1
Multiple forms in one form (get rid of the
hinderance of stateless)
................................
..........................
80
11.1.1
Use <s:doubleselect>
................................
................................
................................
....................
80
11.2
Persist an object through several forms
................................
................................
................................
..
80
11.2.1
Pass completed object data to an fro between action and form via hidden fields
................................
80
11.2.2
Use the scoped
-
model driven interceptor
................................
................................
........................
80
11.2.3
Use the Struts2 conversation plugin
................................
................................
...............................
80
11.3
Internationalization [i18n, localization]
................................
................................
................................
.
80
11.4
Redirecting to the requested page after a login prompt
................................
................................
............
81
11.5
Authentication, login [check user is logged in before executing action]
................................
...................
83
11.6
Managing user rights [permissions]
................................
................................
................................
.......
83
11.7
Downloading a file
................................
................................
................................
...............................
83
11.8
Uploading a file
................................
................................
................................
................................
...
83
11.9
Emulating template calls
................................
................................
................................
......................
84
11.10
Displaying error: css class
................................
................................
................................
.................
84
11.11
Downloading a file
................................
................................
................................
...........................
84
11.12
Setting the date of an element
................................
................................
................................
...........
86
12
Troubleshooting
................................
................................
................................
................................
......
86
12.1
Eclipse
................................
................................
................................
................................
................
86
12.2
Struts
................................
................................
................................
................................
..................
87
13
Questions to search
................................
................................
................................
................................
..
87
14
To Add
................................
................................
................................
................................
...................
87
15
To research
................................
................................
................................
................................
.............
87
16
Security concerns
................................
................................
................................
................................
....
87
17
JSP
................................
................................
................................
................................
.........................
88
17.1
Accessing a struts action from within jsp
................................
................................
...............................
88
3
Written and/or compiled from
other
sources by François Hill
201
0
.
12
First ve
rsion
2011.05
2012.0
4
.
This memo is by no means an exhaustive documentation on the subject matter. It is meant as
a
dynamic
support
document primarily for the use of the author and as such
addresses
his needs and concerns first and foremost
. This is not
a tutorial! (fundamental points may well be omitted)
The author cannot be held responsible
for
any use which may be made of the information contained therein.
Use at own
discretion.
1
Ref. & doc.
Tutorials:
http://struts.apache.org/2.x/tutorials.html
http://www.tutorialspoint.com/struts_2/index.htm
Reference:
http://stru
ts.apache.org/2.2.3/docs/home.html
http://struts.apache.org/2.x/docs/core
-
developers
-
guide.html
2
Setting up
2.1
Jar dependencies
http://struts.apache.org/2.3.4/struts2
-
core/dependencies.html
2.1.1
R
equired
2.1.1.1
S
truts (2.3.
4
)
struts2
-
core
-
2.3.4.1.jar
2.1.1.2
Direct non optional dependencies ("Project dependencies")
commons
-
fileupload
-
1.2.2.jar
commons
-
io
-
2.0.1.jar
ognl
-
3.0.5.
jar
xwork
-
core
-
2.3.4.1.jar
freemarker
-
2.3.1
9
.jar
2.1.1.3
Dependencies' dependencies ("Project Transitive Dependencies")
asm
-
3.3.jar
asm
-
commons
-
3.3.jar
asm
-
tree
-
3.3.jar
commons
-
beanutils
-
1.8.0.jar
commons
-
collections
-
3.1.jar
commons
-
digester
-
2.0.jar
commons
-
lang
-
2
.4.jar
commons
-
logging
-
1.1.1.jar
commons
-
validator
-
1.3.1.jar
javassist
-
3.11.0.GA.jar
commons
-
lang3
-
3.1.jar
spring
-
asm
-
3.0.5.RELEASE.jar
oro
-
2.0.8.jar
sslext
-
1.2
-
0.jar
Notice:
sslext
-
1.2
-
0.jar
is marked as a "project transitive dependency" on the struts'de
pendency page, however it
is not present in the
struts
-
2.3.4.1
-
all.zip
distribution.
Struts, dependencies and transitive dependencies should be placed in the
Webcontent/WEB
-
INF/lib folder:
4
and included on the build path
as follows (through project > Pr
operties):
5
2.1.1.4
"Provided"
jsp
-
api2.0jar
servlet
-
api2.4
These dependencies will be provided by the server library. The
y
will however be necessary to compile the project, so
we'll need to include them (here, by including the server (Tomcat v5.5) library).
6
2.1.2
Optional
2.1.2.1
Struts optional
For using struts optional features I guess (different from plugins)
junit4.8.2
-
jar
struts
-
annotations1.0.5
-
jar
velocity
1.6.3
-
jar
velocity
-
tools
1.3
-
jar
spring
-
core3.0.5.RELEASE
-
jar
testng
5.1
(
jdk15
)
2.1.2.2
For use of spring & spring plugi
n
struts2
-
spring
-
plugin
-
2.3.4.1.jar
Spring jars for IoC:
Spring jar for transaction management:
spring
-
tx
-
3.0.5.RELEASE.jar
TODO
2.1.2.3
For use of junit testing
j
unit4.8.2
-
jar
(struts optional, see section above)
struts2
-
junit
-
plugin
-
2.3.4.1.jar
2.1.3
Other inte
resting utilites (non struts)
2.1.3.1
iBATIS
ibatis
-
sqlmap
-
2.2.0.jar
ibatis
-
common
-
2.2.
0.jar
7
spring
-
ibatis.jar
(
Provides spring utilities to build an iBATIS SqlMapper)
commons
-
dbcp
-
1.3.jar
("Common Datasource", to provide link to
data source
to
iBATIS
)
If using ibatis with spring, the following jar will be necessary to let spring manage
(or synchronize with)
ibatis
transactions [or something very much like that] :
spring
-
tx
-
3.0.5.RELEASE.jar
2.1.3.2
Logging
log4j
-
1.2.14.jar
2.2
When add
ing/touching the jar config
1.
Refresh project file system (in "Navigator view")
2.
Recheck projet properties and the build path
3.
Project > Clean
4.
Restart the server
3
Configuring struts
3.1
Configuring the framework
http://struts.apache.org/2.0.14/docs/configuration
-
files.html
F
rom a Struts developer point of view, the one required configuration file used by the framework is
web.xml
. From
here, you have full control over how Struts configur
es both itself and your application. By default, Struts will load a
set of internal configuration files to configure itself, then another set to configure your application, however it is
possible to build an entire Struts application without writing a sing
le configuration file other than
web.xml
.
The table lists the files that you can use to configure the framework for your application. Some configuration files can
be reloaded dynamically. Dynamic reloading makes interactive development possible. See
Reloading configuration
for more.
File
Optional
Location (relative to
webapp)
Purpose
web.xml
no
/WEB
-
INF/
Web deployment descriptor to include all necessary
framework components
struts.xml
yes
/WEB
-
INF/classes/
Main configuration,
contains result/view types, action
mappings, interceptors, and so forth
struts.properties
yes
/WEB
-
INF/classes/
Framework properties
struts
-
default.xml
yes
/WEB
-
INF/lib/
Struts2
-
core.jar
Default configuration provided by Struts
struts
-
default.vm
yes
/WEB
-
INF/classes/
Default macros referenced by
velocity.properties
struts
-
plugin.xml
yes
At the root of a plugin
JAR
Optional configuration files for
Plugins
in the same format as
struts.xml
.
velocity.properties
yes
/WEB
-
INF/classes/
Override the default
Velocity
configuration
3.1.1
Via file struts.properties
“
Struts2
uses a number of properties that can be changed to fit your needs. To change any of these properties, specify
the property key and
value in a
struts.properties
file. The properties file can be locate
d
anywhere on the
classpath, but it is typically found under
/WEB
-
INF/classes
”
(
http://struts.apache.org/2.0.14/d
ocs/strutsproperties.html
8
http://www.tutorialspoint.com/struts_2/struts_configuration.htm
3.1.2
Via file web.xml and tag <init
-
param>
Redefine the property
3.1.3
Via file struts.xml a
nd tag <constant>
Redefine the property
See section under struts.xml
3.2
Struts.xml
3.2.1
Doc :
http://struts.apache.org/2.0.14/docs/action
-
configuration.html
http://www.roseindia.net/struts/
Struts2
/struts
-
xml.shtml
http://www.javabeat.net/articles/67
-
s
truts
-
20
-
introduction
-
and
-
validations
-
using
-
annotatio
-
1.html
http://struts.apache.org/2.x/docs/plugins.html
http://struts.apache.org/2.x/docs/wildcard
-
method
-
selection.html
http://struts.apache.org/2.0.14/docs/strutsxml
-
examples.html
(struts.xml DTD)
3.2.2
Example
<
struts
>
<
constant
name
=
"struts.enable.DynamicMethodInvocation"
value
=
"false"
/>
<
constant
name
=
"struts.devMode"
value
=
"true"
/>
<
constant
name
=
"struts.custom.i18n.resources"
value
=
"global"
/>
<!
--
Have spring create the objects rather t
han, by default, struts :
--
>
<
constant
name
=
"struts.objectFactory"
v
alue
=
"org.apache.
Struts2
.spring.
StrutsSpringObjectFactory"
/>
<
package
name
=
"default"
extends
=
"struts
-
default"
namespace
=
"/"
>
<!
--
==============================
===================================
GLOBAL RESULTS
=================================================================
--
>
<
global
-
results
>
<
result
name
=
"login"
type
=
"redirectAction"
>
login_displayNew
</
result
>
<
result
name
=
"error_login_requested"
9
type
=
"redirectAction"
>
login_loginRequested
</
result
>
<
result
name
=
"error_data_source_access"
>
/jsp/err/data_source_access/index.jsp
</
result
>
<
result
name
=
"error
_user_rights"
>
/jsp/err/user_rights/index.jsp
</
result
>
<
result
name
=
"error_invalid_param"
>
/jsp/err/invalid_param/index.jsp
</
result
>
<
result
name
=
"error_general"
>
/jsp/err/general/index.jsp
</
result
>
</
global
-
res
ults
>
<
global
-
exception
-
mappings
>
<!
--
Forward a specific, non
-
caught exception, to a given action :
--
>
<
exception
-
mapping
exception
=
"fhi_webapp_template.exceptions.UserNotLoggedInException"
result
=
"error_login_requested"
/>
<!
--
Forward a
ny
non caught exception
to a given action
:
--
>
<
exception
-
mapping
exception
=
Exception
"
result
="
error
_general
"/>
</
global
-
exception
-
mappings
>
<!
--
=================================================================
INTERCEPTORS
========
=========================================================
--
>
<!
—
-
Add to the
the <interceptors> provided by the extended package
--
>
<
interceptors
>
<!
—
-
Extend the following interceptor stack (
provided by the extended package
)… :
--
>
<
interceptor
-
stac
k
name
=
"defaultStack"
>
<!
—
-
...by extending the following particular interceptor :
--
>
<
interceptor
-
ref
name
=
"validation"
>
<!
—
-
...by adding the following parameter :
--
>
<!
—
-
(Here we specify that this particular interceptor should not be
called on these specified actions)
--
>
<
param
name
=
"excludeMethods"
>
displayNew, logout
</
param
>
</
interceptor
-
ref
>
</
interceptor
-
stack
>
</
interceptors
>
<!
--
=================================================================
BE
GINNING OF ACTIONS
=================================================================
--
>
<
action
name
=
"login"
>
<
result
type
=
"redirectAction"
>
login_
</
result
>
</
action
>
3.2.3
DTD
The order of elements counts!
Otherwise you could get an exception li
ke:
org.xml.sax.SAXParseException
: The content of element type "package" must match "(result
-
types?,interceptors?,default
-
interceptor
-
ref?,default
-
action
-
ref?,default
-
class
-
ref?,global
-
results?,global
-
exception
-
mappings?,action*)".
3.2.4
constant names [confi
guring struts, configuration]
The tag
<constant>
allow to redefine a value contained in the file
struts.properties
This file allows
changing
a number of struts’ properties to suit our needs.
).
See also: configuration files:
http://struts.apache.org/2.0.14/docs/configuration
-
files.html
To research
: does
:
3.2.4.1
constant name="struts.objectFactory”
Defines what factory will be used to create the objects.
In the example abo
ve, we request that objects be created by the the spring factory rather than the default struts factory.
10
3.2.5
Package, namespace
http://struts.apache.org/2.x/docs/namespace
-
configura
tion.html
package namespace + action name = URL to be called from browser
extends : here we ‘extend’ the struts default package (see interceptor)
The namespace affects also all links on page :
Eg. If current page is namespace/page1.action, an on this p
age there is a link “home.action”, the actual action looked
up by struts will be namespace/home.action
Seems also to affect how external files (js and css) are loaded. (namespace seems to be inserted before requested rel
path)
3.2.5.1
Extend package
Is it possibl
e to expand several package [multiple package extension, inheritance]
?
o
Very few resources on the web.The question is asked here :
http://grokbase.com/t/struts.apache.org/user/2009/04/help
-
can
-
we
-
set
-
multiple
-
extended
-
packages/28sw2jmmefx7mo2pzntagoinr4ma
but there is no answer provided.
o
Here too :
http://struts.1045723.n5.nabble.com/Package
-
extends
-
td3477910.html
o
From experience with FWL, yes:
<!
--
Import the struts
config
files of the
fwl
-
plugins
necessary for our project :
--
>
<
include
file
=
"/com/sfr/fwl/plugins/plugin_login/s
truts/config.xml"
/>
<
include
file
=
"/com/sfr/fwl/plugins/plugin_rights/struts/config.xml"
/>
<
include
file
=
"/com/sfr/fwl/plugins/plugin_page_error/struts/config.xml"
/>
<
include
file
=
"/com/sfr/fwl/plugins/plugin_log4j/struts/config.xml"
/>
<!
--
Def
ine the struts
config
for our project :
Extending other packages "imports" their defined
interceptors
and
interceptor
stacks
Careful ! To extend a package, you first have to include the file that contains it.
--
>
<
package
name
=
"project__
config"
namespace
=
"/"
extends
=
"fwl_plugins_plugin_login__config ,
fwl_plugins_plugin_rights__config,
fwl_plugins_plugin_page_error__config ,
fwl_plugins_plugin_log4j__config
"
>
3.2.6
Interceptors
See section ‘Interceptors’
3.2.7
Actions
3.2.7.1
Wildcard characters
http://struts.apache.org/2.x/docs/wildcard
-
mappings.html
:
Example:
(…)
<
action
name
=
"matriceSeuils
.*"
method
=
"{1}"
class
=
"com.sfr.cp.dashboard.actions.MatriceSeuilsAction"
>
<
result
name
=
"success"
>
jsp/matriceSeuils/edition.jsp
</
result
>
If struts fails to set one of the inputs (e.g. types don’t match) given bu the user, it seems it
automatically look
s for the “input” result :
<
result
name
=
"input"
>
jsp/matriceSeuils/edition.jsp
</
result
>
<
result
name
=
"error"
>
jsp/matriceSeuils/edition.jsp
</
result
>
<
result
name
=
"download"
type
=
"stream"
>
<
param
name
=
"contentDisposition"
>
attachment;filename=m
atrice_seuils.csv
</
param
>
<
param
name
=
"contentType"
>
application/vnd.ms
-
excel
</
param
>
<
param
name
=
"inputName"
>
outputMatriceSeuilsAsFile
</
param
>
<
param
name
=
"bufferSize"
>
1024
</
param
>
</
result
>
</
action
>
(…)
11
Example :
<action name=
"/edit*"
class=
"org.apache.struts.webapp.example.Edit{1}Action"
>
<result name=
"failure"
>/mainMenu.jsp</result>
<result>{1}.jsp</result>
</action>
If the wildcard character * catch
es nothing, then by default the (default) execute() function is called ().
“Mappings are matched against the request in the order they appear in the framework's configuration file.
If
more than one pattern matches the last one wins, so less specific patter
ns must appear before more specific ones.
However, if the request URL can be matched against a path without any wildcards in it, no wildcard matching is
performed and order is not important. Also, note that wildcards are not greedy, meaning they only match
until the
first occurrence of the following string pattern.”
3.2.8
Results
http://struts.apache.org/2.x/docs/result
-
configuration.html
http://struts.apache.org/2.x/docs/result
-
types.html
3.2.8.1
Redirection
Done either by redirect or redirectAction
.
The browser will show the url of the redirection (and not the original url).
3.2.8.1.1
Redirect
http://struts.apache.org/2.x/docs/redirect
-
result.html
Redirects to a url. This also allows us to pass info to the target through the addition of parameters to the url
<
result
name
=
"success"
type
=
"redirect"
>
<
param
name
=
"location"
>
foo.jsp?foo=${bar}
</
param
>
<
param
name
=
"parse"
>
true
</
param
>
<
param
name
=
"encode"
>
true
</
param
>
</
result
>
<!
--
The redirect
-
action
url
generated will be :
/genReport/generateReport.jsp?reportType=pie&width=100&height=100#summar
y
--
>
<
action
name
=
"gatherReportInfo"
class
=
"..."
>
<
result
name
=
"showReportResult"
type
=
"redirect"
>
<
param
name
=
"location"
>
generateReport.jsp
</
param
>
<
param
name
=
"namespace"
>
/genReport
</
param
>
<
param
name
=
"reportType"
>
pie
</
param
>
<
param
name
=
"width"
>
100
</
param
>
<
param
name
=
"height"
>
100
</
param
>
<
param
name
=
"anchor"
>
summary
</
param
>
</
result
>
</
action
>
<
result
name
=
"fwl_plugins_plugin_login__session_expired"
type
=
"
redirect"
>
<
param
name
=
"location"
>
fwl_plugins_plugin_login__login_required.action
</
param
>
<
param
name
=
"session_expired"
>
true
</
param
>
</
result
>
Url called
: fwl_plugins_plugin_login__login_required.action?session_expired=true
3.2.8.1.2
Redi rectActi on
The difference
with redirect is in the format of the redirection location: with redirect it is a url, with redirectAction an
action.
Dynamic redirectAction :
<
action
name
=
"fragment"
class
=
"FragmentAction"
>
<
result
name
=
"next"
type
=
"redirectAction"
>
${nextAction}
</
r
esult
>
</
action
>
3.2.8.1.3
Compari son to a si mpl e di recti on to a UI fi l e (e.g. a jsp)
Advantages
-
the request goes through the action to which it is redirected ensuring that action
-
related processing can be
done, notably : getting the UI labels from the .properties
file.
12
Shortcomings :
-
“
the action (action instance, action errors, field errors, etc) that was just executed
[i.e. the first one]
is lost and
no longer available. This is because actions are built on a single
-
thread model
” [struts doc]
See :
http://stackoverflow.com/questions/1070111/can
-
i
-
propagate
-
Struts2
-
actionerrors
-
between
-
different
-
action
-
classes
3.2.8.2
Chaining
<
result
name
=
"
chain
_to_next
"
type
=
"chain"
>
nextAction
</
result
>
<!
--
Chaining an error to an action (instead of just to the
jsp
) allows us to
-
Keep the VS (even if this may still be possible
otherwise see struts doc)
-
Add processing (logging & stuff) done inside the action (same)
-
Customize error messages displayed
--
>
<
result
name
=
"fwl_plugins_
plugin_rights__error_not_authorized"
type
=
"chain"
>
fwl_plugins_plugin_rights__error_not_authorized
</
result
>
Just
like redirection
,
“t
his result invokes an entire
other action, complete with it
s own interceptor stack and result.
”
This means we have the same shortcomings.
Chaining is discouraged by struts’ doc itself.
[FHI because it should not be used ‘commonly’ in place of other
mecanisms. However in some cases it can be useful]
See also :
http://struts.apache.org/2.0.14/docs/action
-
chaining.html
http://stackoverflow.com/questions/4956603/action
-
redirect
-
in
-
struts
-
xml
See also
4.3.3
chain
interceptor
See also
4.3.9.1
action redirection for exceptions
3.2.8.3
Using parameters in the results
http://struts.apache.org/2.x/docs/parameters
-
in
-
configuration
-
results.html
3.2.9
Global results
Ex
:
<
struts
>
<
package
name
=
"calendar_list"
extends
=
"struts
-
project"
namespa
ce
=
"/"
>
<
global
-
results
>
<
result
name
=
"success"
>
/jsp/calendar_list/index.jsp
</
result
>
<
result
name
=
"input"
>
/jsp/calendar_list/index.jsp
</
result
>
<
result
name
=
"error"
>
/jsp/calendar_list/index.jsp
</
result
>
</
gl
obal
-
results
>
<
action
name
=
"calendar_list_input"
class
=
"calendar_list_act"
/>
<
action
name
=
"calendar_list_delete"
class
=
"calendar_list_delete_act"
/>
</
package
>
</
struts
>
3.2.10
Global exception mappings
work with the exception interceptor, see this.
3.2.11
st
ruts.xml and the value stack
struts.xml is aware of the stack and can evaluate OGNL expressions.
3.2.11.1
Accessing elements of the value stack
<
action
name
=
"login_*"
method
=
"{1}"
class
=
"login_action"
>
13
<
result
name
=
"remembered"
type
=
"redirect"
>
<
param
name
=
"loc
ation"
>
${rememberedAction}?${rememberedActionParams}
</
param
>
<
param
name
=
"parse"
>
true
</
param
>
</
result
>
will summon methods getRememberedAction() and getRememberedActionParams() from the underlying action class.
Calling an action with a param
See if po
ssible
<
action
name
=
"login_*"
method
=
"{1}"
class
=
"login_action"
>
<!
--
Here define a variable
--
>
<var name=”state” value=”read” /> <!
--
Is this possible ?
--
>
<
result
name
=
"remembered"
type
=
"redirect"
>
<
param
name
=
"location"
>
${rememberedAction}?${reme
mberedActionParams}
</
param
>
<
param
name
=
"parse"
>
true
</
param
>
</
result
>
3.2.12
Context scoped objects
The following contexts aka “JSP/serv
let scoped contexts (objects)”
are available
:
(shown here with jsp struts tags)
<
s:property
value
=
"%{#application.myApplica
tionAttribute}"
/>
<!
--
application scope
--
>
<
s:property
value
=
"%{#session.mySessionAttribute}"
/>
<!
--
session scope
--
>
<
s:property
value
=
"%{#request.myRequestAttribute}"
/>
<!
--
request scope
--
>
<
s:property
value
=
"%{#parameters.myParam
eter}"
/>
<!
--
request parameter scope
--
>
<
s:property
value
=
"%{#myContextParam}"
/>
<!
--
local variables e.g.defined with s:set
--
>
These contexts are also available in config files like
struts.xml:
<action
name
=
"Login"
cl
ass
=
"LoginAction"
>
<result type=
"redirectAction"
>
<param name=
"actionName"
>${#session[
'lastAction'
]}</param>
3.2.13
Splitting struts.xml in several files
http://struts.apache.org/2.0.14/docs/can
-
we
-
break
-
up
-
a
-
large
-
strutsxml
-
file
-
into
-
smaller
-
pieces.html
Example:
<!DOCTYPE struts PUBLIC
"
-
//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/st
ruts
-
2.0.dtd">
<struts>
<include file="Home.xml"/>
<include file="Hello.xml"/>
<include file="Simple.xml"/>
<include file="/util/POJO.xml"/>
<include file="/com/initech/admin/admin
-
struts.xml"/>
</struts>
Root package: (modules/str
uts.xml)
<!
DOCTYPE
struts
PUBLIC
"
-
//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts
-
2.0.dtd"
>
<
struts
>
14
<
package
name
=
"struts
-
modules"
extends
=
"struts
-
default"
namespace
=
"/"
>
<
interceptors
>
<
!
--
Define the additional (custom) interceptors
:
--
>
<
interceptor
name
=
"authorized"
class
=
"com.sfr.webapp.interceptors.MyInterceptor"
/>
<!
--
Define the stack(s)
:
--
>
<
interceptor
-
stack
name
=
"paramsPrepareParamsStackWithAuthorized"
>
<
interc
eptor
-
ref
name
=
"exception"
/>
(...)
</
interceptor
-
stack
>
</
interceptors
>
</
package
>
</
struts
>
Extension of the root package:
<
struts
>
<
package
name
=
"struts
-
project"
extends
=
"struts
-
modules"
namespace
=
"/"
>
<!
--
Default stack to be used
:
--
>
<
default
-
interceptor
-
ref
name
=
"paramsPrepareParamsStackWithAuthorized"
/>
<
global
-
results
>
<
result
name
=
"error_login_required"
type
=
"redirect"
>
login_input
</
result
>
(...)
</
global
-
results
>
<
global
-
exception
-
mappings
>
<
exception
-
ma
pping
exception
=
"MyExceptionClass"
result
=
"myGlobalResult"
/>
<!
--
Any non caught exception :
--
>
<!
--
<exception
-
mapping exception="Exception" result="error_general"/>
--
>
</
global
-
exception
-
mappings
>
</
package
>
<!
--
Include specific
packages
:
--
>
<
include
file
=
"/struts/project/home.xml"
/>
<
include
file
=
"/struts/project/calendar.xml"
/>
<
include
file
=
"/struts/project/service.xml"
/>
<
include
file
=
"/struts/project/service_list.xml"
/>
<
include
file
=
"/stru
ts/project/login.xml"
/>
</
struts
>
Specific struts packages: (example:
struts/project/home.xml)
<
struts
>
<
package
name
=
"calendar"
extends
=
"struts
-
project"
namespace
=
"/"
>
<
action
name
=
"calendar_input"
(...)
</
action
>
(...)
Struts roo
t file: (conf/struts.xml)
<
struts
>
<
include
file
=
"/struts/modules/struts.xml"
/>
<
include
file
=
"/struts/project/struts.xml"
/>
</
struts
>
4
Interceptors & Interceptor stacks
4.1
Doc
http://st
ruts.apache.org/2.0.14/docs/interceptors.html
4.2
Interceptor, Interceptor stack
Action lifecycle
:
15
Interceptors
(
can
)
execute code before and after an Action is invoked
. They
can
also
prevent an action from firing
(validation double
-
submit …) or change
its state.
Interceptors
are defined in a
stack
t
hat specifies the execution order.
This stack is described in the struts.xml file.
Struts2
comes with a set of
pre
-
defined interceptors and interceptor stacks
. In the example below we use the
default interce
ptor stack (by extending it)
Interceptor stack
4.2.1
Ready
-
to
-
use stacks
Struts defines several ready
-
to
-
use stacks (see file
struts
-
default.xml
or
http://struts.apache.org/2.0.14/docs/interc
eptors.html
) :
basicStack, validationWorkflowStack, jsonValidationWorkflowStack, fileUploadStack,
...,
defaultStack,
paramsPrepareParamsStack
etc.
The default stack is made up of the following interceptors :
(in
struts
-
default.xml
)
<
interceptor
-
stack
name
=
"defaultStack"
>
<
interceptor
-
ref
name
=
"exception"
/>
<
interceptor
-
ref
name
=
"alias"
/>
<
interceptor
-
ref
name
=
"servletConfig"
/>
<
interceptor
-
ref
name
=
"prepare"
/>
<
interceptor
-
ref
name
=
"i18n"
/>
<
interceptor
-
ref
name
=
"chain"
/>
<
interceptor
-
ref
name
=
"
debugging"
/>
<
interceptor
-
ref
name
=
"profiling"
/>
<
interceptor
-
ref
name
=
"scopedModelDriven"
/>
<
interceptor
-
ref
name
=
"modelDriven"
/>
<
interceptor
-
ref
name
=
"fileUpload"
/>
<
interceptor
-
ref
name
=
"checkbox"
/>
<
interceptor
-
ref
name
=
"staticParams"
/>
<
interc
eptor
-
ref
name
=
"actionMappingParams"
/>
<
interceptor
-
ref
name
=
"params"
>
<
param
name
=
"excludeParams"
>
dojo
\
..*,^struts
\
..*
</
param
>
</
interceptor
-
ref
>
<
interceptor
-
ref
name
=
"conversionError"
/>
<
interceptor
-
ref
name
=
"validation"
>
<
param
name
=
"excludeMe
thods"
>
input,back,cancel,browse
</
param
>
</
interceptor
-
ref
>
<
interceptor
-
ref
name
=
"workflow"
>
<
param
name
=
"excludeMethods"
>
input,back,cancel,browse
</
param
>
</
interceptor
-
ref
>
</
interceptor
-
stack
>
4.2.2
Defining a stack of one’s ow
n
:
It is possible to define
a stack of one’s own in struts.xml:
By defining all its interceptors :
<
interceptors
>
<
interceptor
-
stack
name
=
"
my
Stack"
>
<
interceptor
-
ref
name
=
"exception"
/>
ActionInvocation encapsulates the
action and the associated
interceptors
. It
knows in which
sequence the interceptors should be
invoked.
The interceptors are called in a
Russian doll
manner :
Interceptor 1
Interceptor 2
Interceptor 3
Action execute()
Interceptor 3
Interceptor 2
Interceptor 1
16
<
interceptor
-
ref
name
=
"alias"
/>
<
interceptor
-
ref
name
=
"validation"
/>
<!
--
Here we
use
the interceptor named 'workflow'
with a specific
param :
--
>
<
interceptor
-
ref
name
=
"workflow"
>
<
param
name
=
"excludeMethods"
>
input,back,cancel,browse
</
param
>
</
interceptor
-
ref>
</
interceptor
-
stack
>
Setting it for a specific action :
<
action
n
ame
=
"*Sample"
method
=
"{1}"
class
=
"vaannila.SampleAction"
>
<
interceptor
-
ref
name
=
"
my
Stack"
/>
<
result
name
=
"populate"
>
/first.jsp
</
result
>
<
result
name
=
"success"
>
/success.jsp
</
result
>
</
action
>
Setting it as the stack for all actions :
<
package
name
=
"my_package"
extends
=
"struts
-
default"
namespace
=
"/"
>
<
default
-
interceptor
-
ref
name
=
"paramsPrepareParamsStackWithAuthorized"
/>
By extending an existing stack :
4.2.3
O
t
her way of extending an interceptor stack : directly in definition of action
<
struts
>
<
pac
kage
name
=
"default"
extends
=
"struts
-
default"
>
<
action
name
=
"*Sample"
method
=
"{1}"
class
=
"vaannila.SampleAction"
>
<!
--
Use the default stack but redefine the param ‘excludeMethods’ of the interceptor
‘validation’
:
--
>
<
interceptor
-
ref
n
ame
=
"defaultStack"
>
<
param
name
=
"validation.excludeMethods"
>
populate
</
param
>
</
interceptor
-
ref
>
<
result
name
=
"populate"
>
/first.jsp
</
result
>
<
result
name
=
"success"
>
/success.jsp
</
result
>
</
action
>
</
package
>
</
struts
>
Interceptors
The inte
rcept() method of each interceptor is called.
List of all interceptors :
http://struts.apache.org/2.0.14/docs/interceptors.html#Interceptors
-
Framework
Interceptors
Here we will detail some of the most useful interceptors :
4.2.4
Interceptor params
http://struts.apache.org/2.0.14/docs/interceptors.html#Intercep
tors
-
MethodFiltering
As well as
its own
(possible)
params
, every (? doc is unclear) interceptor has the following params :
-
excludeMethods
-
method names to be excluded from interceptor processing
-
includeMethods
-
method names to be included in interc
eptor processing (
takes precedence over exclude)
Overriding interceptor params :
http://struts.apache.org/2.0.14/docs/interceptors.html#Int
erceptors
-
InterceptorParameterOverriding
2 methods, see example above
4.3
Interceptors : detail
4.3.1
actionMappingParams
+ params
: Mapping the Http request parameters to Action class
properties
HTML is a String based protocol: the values it sends through a requ
est are strings. Struts tries (via underlying
framework XWorkConverter) to convert these strings to the types expected in the setValue(value_sent_in_request)
functions of the underlying action class using a conversion scheme (TODO see :
-
the conversion me
chanism can be
defined)
If the convertor fails ton
convert:
see interceptor conversionError
http://struts.apache.org/2.0.14/docs/parameters
-
interceptor.html
17
4.3.1.1
Type conversion
http://struts.apache.org/2.2.1/docs/type
-
conversion.html
TODO
4.3.1.1.1
What types should be given to the Action class
properties?
TODO : research this
All Strings
-
> there will be no type
conversion done by struts
o
Advantage : control over the conversion
o
Disadvantage : have to do the conversion yourself
Other types
-
> there will be type conversion done by struts
o
Advantage :
don’t worry about conversion
Use “native” Java classes (i.e. class
es that have not been developed specifically w
ith a struts web
interface in mi
nd
o
Disadvantage : sometimes this poses pb
Ex:
web user interface inputs hours
as:
“00”, “01” … “24” (in a select) .
This is converted to a Java int (0, …, 24). No pb up to there
.
But the other way round (setting the value in the web interface control from the Java value) this
won’t work because the int 0
-
> 9 will be converted to the strings “0”
-
> “9” and not “00”
-
> “09”.
It may be possible (??) to tweak the struts type conv
erter there (but this might be a bit of a hassle)
[Another way to address the given example
-
without dismissing the problem : use different
display/send values on the select, possibly using such a list :
<
s:set
name
=
"listHours"
v
alue
=
"
#{'0':'00','1':'01',
'2':'02','3':'03
','4':'0
4','5':'05','6':'06','7':'07',
…
4.3.1.2
Multiple parameters [arrays, tabular]
Fortunately
HTTP supports submitting multiple parameters of the same name, and Struts will autopopulate a String
array as easily as a single String. So, to
represent the "multi
-
use" business operation in an ActionForm, we can do
this:
private
String
[]
name
s
=
null
;
public
String
[]
get
Names
()
{
return
this
.
names
; }
public
void
set
Names
(
String
[]
names
) {
this
.
names
=
names
; }
Nota
: from my
experience there might be issues with using arrays (instead of lists). The above is given by the struts
doc but I have had trouble running a very similar setup
.
JSP:
<
s:textfield
label
=
"First name"
name
=
"name[]"
/>
<
s:textfield
label
=
"Second name"
name
=
"name[]"
/>
<
s:textfield
label
=
"Third name"
name
=
"name[]"
/>
If using indexes, be sure to instantiate the list on the action side.
It's not mandatory (Struts will do it otherwise upon
receiving the inputs and setting them onto the action) but upon loadi
ng the page before it being submitted to the
action, the values to fill the inputs (e.g.
value="%{array[3]}
) might raise errors.
4.3.1.3
Multiple nested parameters [arrays, tabular]
http:/
/struts.apache.org/2.1.8.1/docs/tabular
-
inputs.html
http://stackoverflow.com/questions/6313790/post
-
an
-
array
-
of
-
custom
-
objects
-
to
-
a
-
struts
-
2
-
ac
tion
4.3.1.3.1
Exampl e:
Jsp
<
form
action
=
"test"
method
=
"post"
>
<
script
type
=
"text/javascript"
>
dojo.require(
"dijit.form.DateTextBox"
);
</
script
>
18
<
div
>
<
input
name
=
"days[0].date"
id
=
"days[0].date"
type
=
"text"
value
=
"
<
s:property
value
=
"days[0].date"
/>
"
maxlength
=
"8"
dojoType
=
"dijit.form.DateTextBox"
/>
<
input
name
=
"days[0].openingHours"
value
=
"
<
s:property
value
=
"days[0].openingHours"
/>
"
maxlength
=
"2"
/>
:
<
input
name
=
"days[0].openingMinutes"
value
=
"
<
s:property
value
=
"days[0].openingMinutes"
/>
"
maxlength
=
"2"
/>
<
input
name
=
"days[0].closingHours"
value
=
"
<
s:property
value
=
"days[0].closingHours"
/>
"
maxlength
=
"2"
/>
:
<
input
name
=
"days[0].closingMinutes"
value
=
"
<
s:property
value
=
"days[0].closingMinutes"
/>
"
maxlength
=
"2"
/>
</
div
>
<
div
>
<
input
name
=
"days[1].date"
id
=
"days[1].date"
type
=
"text"
value
=
"
<
s:property
value
=
"days[1].date"
/>
"
maxlength
=
"8"
dojoType
=
"dijit.form.DateTextBox"
/>
<
inp
ut
name
=
"days[1].openingHours"
value
=
"
<
s:property
value
=
"days[1].openingHours"
/>
"
maxlength
=
"2"
/>
:
<
input
name
=
"days[1].openingMinutes"
value
=
"
<
s:property
value
=
"day
s[1].openingMinutes"
/>
"
maxlength
=
"2"
/>
<
input
name
=
"days[1].closingHours"
value
=
"
<
s:property
value
=
"days[1].closingHours"
/>
"
maxlength
=
"2"
/>
:
<
input
name
=
"days[1].closingMinutes"
value
=
"
<
s:property
value
=
"days[1].closingMinutes"
/>
"
maxlength
=
"2"
/>
</
div
>
<
input
type
=
"submit"
/>
</
form
>
And, better, using an iterator so as to expose the days if they already have value
s on server side (retrieved from data
source :
<
form
action
=
"test"
method
=
"post"
>
<
script
type
=
"text/javascript"
>
dojo.require(
"dijit.form.DateTextBox"
);
dojo.require(
"dijit.form.Button"
);
</
script
>
<
s:iterator
var
=
"it"
value
=
"days"
st
atus
=
"status"
>
<
div
id
=
"day_
<
s:property
value
=
"%{#status.index}"
/>
"
>
<
button
dojoType
=
"dijit.form.Button"
type
=
"button"
>
Delete
</
button
>
<
input
name
=
"days[
<
s:property
value
=
"%{#status.index}"
/>
].date"
19
id
=
"days[
<
s:property
val
ue
=
"%{#status.index}"
/>
].date"
type
=
"text"
value
=
"
<
s:property
value
=
"days[#status.index].date"
/>
"
maxlength
=
"8"
dojoType
=
"dijit.form.DateTextBox"
/>
<
input
name
=
"days[
<
s:property
value
=
"%{#
status.index}"
/>
].openingHours"
value
=
"
<
s:property
value
=
"days[#status.index].openingHours"
/>
"
Enter the password to open this PDF file:
File name:
-
File size:
-
Title:
-
Author:
-
Subject:
-
Keywords:
-
Creation Date:
-
Modification Date:
-
Creator:
-
PDF Producer:
-
PDF Version:
-
Page Count:
-
Preparing document for printing…
0%
Σχόλια 0
Συνδεθείτε για να κοινοποιήσετε σχόλιο