2. Agenda
What is Struts ?
Features
How Struts works?
Request – Response Pipeline
Different components of Struts
Difference between Struts 1 and Struts 2
Creating your first Struts 2 Application
2
3. Background of Struts 2
Not Struts 1.x!
EE5 Web Framework
Originally OpenSymphony WebWork
WebWork + Struts + Apache
Incubator
Struts 2 was hatched in „07
3
8. Features
• Simple Architecture
• Spring as default inversion of control container
8
9. Features
• Simple Architecture
• Spring as default inversion of control container
• Page-based Navigation
9
10. Features
• Simple Architecture
• Spring as default inversion of control container
• Page-based Navigation
• Built-in Ajax Support: DWR and Dojo
10
11. Features
• Simple Architecture
• Spring as default inversion of control container
• Page-based Navigation
• Built-in Ajax Support: DWR and Dojo
• Much better client-side validation support
11
12. Features
• Simple Architecture
• Spring as default inversion of control container
• Page-based Navigation
• Built-in Ajax Support: DWR and Dojo
• Much better client-side validation support
• JSF Support
12
13. Features
• Simple Architecture
• Spring as default inversion of control container
• Page-based Navigation
• Built-in Ajax Support: DWR and Dojo
• Much better client-side validation support
• JSF Support
• Built-in support for testing with StrutsTestCase
13
24. Different Components of Struts
Core Component – Interceptor, Action & Result
Other concept – ValueStack, OGNL, Configuration Files,Validations
24
25. Interceptors
They provide a way to supply pre-processing and post-processing around
the action.
examples include double-submit guards, type conversion, object population,
validation, file upload, page preparation, exception handling
Not thread safe
<interceptors>
<interceptor name="autowiring“ class="interceptor.ActionAutowiringInterceptor"/>
</interceptors>
<action name="my" class="com.test.MyAction" >
<result>view.jsp</result>
<interceptor-ref name="autowiring"/>
</action>
25
26. Interceptor Stack
An interceptor has a specific role
Parameter interception
Validation
Workflow
Named “stacks” provide pluggable lists pre-assembled for
goal specific cases
defaultStack
fileUploadStack
modelDrivenStack
paramsPrepareParamsStack
26
27. Common Interceptors
Interceptor Description
Checkbox Interceptor Adds automatic checkbox handling code that detect an unchecked
checkbox and add it as a parameter with a default (usually 'false')
value.
Create Session Create an HttpSession automatically, useful with certain
Interceptor Interceptors that require a HttpSession to work properly (like the
TokenInterceptor)
File upload Interceptor An Interceptor that adds easy access to file upload support.
I18n Interceptor Remembers the locale selected for a user's session.
Logger Interceptor Outputs the name of the Action.
ExecuteAndWait Executes the Action in the background and then sends the user off
Interceptor to an intermediate waiting page.
27
28. Common Interceptors Cont’d
Interceptor Description
Scope Interceptor Simple mechanism for storing Action state in the session or
application scope.
Parameters Interceptor Sets the request parameters onto the Action.
Roles Interceptor Action will only be executed if the user has the correct JAAS role.
Profiling Interceptor Activate profiling through parameter
Validation Interceptor Performs validation using the validators defined in action-
validation.xml
Exception Interceptor Maps exceptions to a result.
Cookie Interceptor Inject cookie with a certain configurable name / value into action.
28
29. Timer Interceptor
Stopwatch feature for action execution
“starts” before your action
“stops” afterward
Writes performance timings to log
<interceptors> <interceptors>
<interceptor-stack name="stackWithTimer"> <interceptor-stack name="stackWithTimer">
<interceptor-ref name="timer"/> <interceptor-ref name="defaultStack"/>
<interceptor-ref name="defaultStack"/> <interceptor-ref name="timer"/>
</interceptor-stack> </interceptor-stack>
</interceptors> </interceptors>
records action's execution with interceptors records only the action's execution time
29
31. Actions
Extend ActionSupport
ThreadLocal (safe)
Contain your domain model or can be model driven
May contain multiple methods
Easy to test!
31
33. Result
What should be returned to requester?
Many provided out of the box
It‟s easy to write your own
Graphics
JSON
PDF
It‟s another configurable object
33
34. Result Types
Result Type Description
Chain Result Used for Action Chaining
Used for web resource integration,
Dispatcher Result
including JSP integration
FreeMarker Result Used for FreeMarker integration
HttpHeader Result Used to control special HTTP behaviors
Redirect Result Used to redirect to another URL (web resource)
34
35. Result Types Cont’d
Result Type Description
Redirect Action Result Used to redirect to another action mapping
Used to stream an InputStream back to the browser
Stream Result
(usually for file downloads)
Velocity Result Used for Velocity integration
Used to display the raw content of a particular page
PlainText Result
(i.e jsp, HTML)
Tiles Result Used to provide Tiles integration
35
36. Result Example
<action …>
<result name="success" type="dispatcher">
/employee/list.jsp
</result>
</action>
name and type are optional
name defaults to success
type default can be set by package
36
37. ValueStack & OGNL
A ValueStack is a place where all the data related to
action and the action itself is stored
OGNL is a mean through which the data in the
ValueStack is manipulated.
37
38. ValueStack
• Leverages the OGNL framework
Object Graph Navigation Language
• Extends OGNL to support searching stack
Top down to locate object/property
• Where Interceptors put/get object data
• Thread Safe
• ActionContext.getContext().getValueStack()
Map<String, Object> context = new HashMap<String, Object>();
context.put("key", "some object");
context.put("key2", "another object");
ActionContext.getContext().getValueStack().push(context);
38
40. ValueStack
The Action instance is always pushed onto the value stack and since the stack is the
OGNL root, references to Action properties can omit the # marker.
<s:property value=“customer.address"/>
But, to access other objects in the ActionContext, we must use the # notation so
OGNL knows not to look in the root object, but for some other object in the
ActionContext.
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session['mySessionPropKey']"/> or
<s:property value="#request['myRequestPropKey']"/>
The ActionContext is also exposed to Action classes via a static method.
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
40
41. ValueStack
The Action instance is always pushed onto the value stack and since the stack is the
OGNL root, references to Action properties can omit the # marker.
<s:property value=“customer.address"/>
But, to access other objects in the ActionContext, we must use the # notation so
OGNL knows not to look in the root object, but for some other object in the
ActionContext.
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session['mySessionPropKey']"/> or
<s:property value="#request['myRequestPropKey']"/>
The ActionContext is also exposed to Action classes via a static method.
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
41
42. ValueStack
The Action instance is always pushed onto the value stack and since the stack is the
OGNL root, references to Action properties can omit the # marker.
<s:property value=“customer.address"/>
But, to access other objects in the ActionContext, we must use the # notation so
OGNL knows not to look in the root object, but for some other object in the
ActionContext.
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session['mySessionPropKey']"/> or
<s:property value="#request['myRequestPropKey']"/>
The ActionContext is also exposed to Action classes via a static method.
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
42
43. Type Conversions
OGNL uses reflection to convert types
JavaBeans convention provides “hint”
Custom converters can be added
Scope
Bean/Model
Action
Application
43
44. Configuration Files
File Optional Location 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.prop Yes /WEB_INF/classes Framework properties
erties
Strusts.defa Yes /WEB-INF/lib/ Default configuration provided by
ult.xml struts2-core.jar Struts
44
47. struts-default.xml
Most of your packages will extend this
Directly/Indirectly
Contains about everything you need
Packages form inheritance hierarchies
The key sections are
<package name=“base“ extends="struts-default">
package <result-types>…</result-types>
result-types <interceptors><interceptor-stack name="starterStack">
interceptors/stacks <interceptor-ref name="timer" />
<interceptor-ref name="scopedModelDriven" />
<interceptor-ref name="paramsPrepareParamsStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="starterStack" />
</package>
47
48. Constant Configuration
Modify framework and plug-in behavior
Can be declared at multiple levels
Searched in the following order
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml
Subsequent files override previous ones
48
50. Simple Field Example
Form
<s:textfield key="age"/>
Action
private int age; get/set
Validator <ActionClassName>-validation.xml
<field name="age">
<field-validator type="int">
<param name="min">13</param>
<param name="max">19</param>
<message>must be between ${min} and ${max}, current value is ${bar}</message>
</field-validator>
</field>
50
51. Validator Types
conversion
date
email
short – int – long - double
regex <takes a regular expression>
required
requiredstring
stringlength
url
visitor - conditionalvisitor
fieldexpression <resolves an OGNL expression>
expression <resolves an OGNL expression>
51
52. Non-Field vs Field Validation
<validators>
<validator type="expression">
<param name="expression“> ( (a==b) && (b==c) )</param>
<message>all three fields must be the same></message>
</validator>
</validators>
<field name="email_address">
<field-validator type="required">
<message>You cannot leave the email address field empty.</message>
</field-validator>
<field-validator type="email">
<message>The email address you entered is not valid.</message> </field-
validator>
</field>
52
54. Action Classes
Struts 1 Struts 2
Struts 1 requires Action classes to An Struts 2 Action may implement
extend an abstract base class. A an Action interface, along with other
common problem in Struts 1 is interfaces to enable optional and
programming to abstract classes custom services. Struts 2 provides a
instead of interfaces. base ActionSupport class to implement
commonly used interfaces. Albeit, the
Action interface is not required. Any
POJO object with a execute signature
can be used as an Struts 2 Action
object.
54
55. Threading Model
Struts 1 Struts 2
Struts 1 Actions are singletons and Struts 2 Action objects are instantiated
must be thread-safe since there will for each request, so there are no
only be one instance of a class to thread-safety issues. (In practice,
handle all requests for that Action. servlet containers generate many
The singleton strategy places
restrictions on what can be done throw-away objects per request, and
with Struts 1 Actions and requires one more object does not impose a
extra care to develop. Action performance penalty or impact
resources must be thread-safe or garbage collection.)
synchronized.
55
56. Action Classes
Struts 1 Struts 2
Struts 1 requires Action classes to An Struts 2 Action may implement
extend an abstract base class. A an Action interface, along with other
common problem in Struts 1 is interfaces to enable optional and
programming to abstract classes custom services. Struts 2 provides a
instead of interfaces. base ActionSupport class to implement
commonly used interfaces. Albeit, the
Action interface is not required. Any
POJO object with a execute signature
can be used as an Struts 2 Action
object.
56
57. Servlet Dependency
Struts 1 Struts 2
Struts 1 Actions have dependencies Struts 2 Actions are not coupled to a
on the servlet API since the container. Most often the servlet
HttpServletRequest and contexts are represented as simple
HttpServletResponse is passed to Maps, allowing Actions to be tested in
the executemethod when an Action isolation. Struts 2 Actions can still access
is invoked. the original request and response, if
required. However, other architectural
elements reduce or eliminate the need
to access the HttpServetRequest or
HttpServletResponse directly.
57
58. Testability
Struts 1 Struts 2
A major hurdle to testing Struts 1 Struts 2 Actions can be tested by
Actions is that theexecute method instantiating the Action, setting
exposes the Servlet API. A third- properties, and invoking methods.
party extension, Struts TestCase, Dependency Injection support also
offers a set of mock object for Struts makes testing simpler.
1.
58
59. Harvesting Input
Struts 1 Struts 2
Struts 1 uses an ActionForm object to Struts 2 uses Action properties as input
capture input. Like Actions, all properties, eliminating the need for a second
ActionForms must extend a base class. input object. Input properties may be rich object
Since other JavaBeans cannot be used types which may have their own properties. The
as ActionForms, developers often Action properties can be accessed from the
create redundant classes to capture web page via the taglibs. Struts 2 also supports
the ActionForm pattern, as well as POJO form
input. DynaBeans can used as an
objects and POJO Actions. Rich object types,
alternative to creating conventional including business or domain objects, can be
ActionForm classes, but, here too, used as input/output objects. The ModelDriven
developers may be redescribing feature simplifies taglib references to POJO
existing JavaBeans. input objects
59
60. Expression Language
Struts 1 Struts 2
Struts 1 integrates with JSTL, so it Struts 2 can use JSTL, but the
uses the JSTL EL. The EL has basic framework also supports a more
object graph traversal, but relatively powerful and flexible expression
weak collection and indexed language called "Object Graph
property support. Notation Language" (OGNL).
60
61. Binding values into views
Struts 1 Struts 2
Struts 1 uses the standard JSP Struts 2 uses a "ValueStack"
mechanism for binding objects into technology so that the taglibs can
the page context for access. access values without coupling your
view to the object type it is rendering.
The ValueStack strategy allows reuse
of views across a range of types which
may have the same property name but
different property types
61
62. Type Conversion
Struts 1 Struts 2
Struts 1 ActionForm properties are Struts 2 uses OGNL for type
usually all Strings. Struts 1 uses conversion. The framework includes
Commons-Beanutils for type converters for basic and common
conversion. Converters are per-class, object types and primitives
and not configurable per instance.
62
63. Validation
Struts 1 Struts 2
Struts 1 supports manual validation Struts 2 supports manual validation via
via a validatemethod on the the validate method and the XWork
ActionForm, or through an extension Validation framework. The Xwork
to the Commons Validator. Classes Validation Framework supports
can have different validation contexts chaining validation into sub-properties
for the same class, but cannot chain using the validations defined for the
to validations on sub-objects. properties class type and the
validation context.
63
64. Control of method execution
Struts 1 Struts 2
Struts 1 supports separate Request Struts 2 supports creating different
Processors (lifecycles) for each lifecycles on a per Action basis via
module, but all the Actions in the Interceptor Stacks. Custom stacks can
module must share the same be created and used with different
lifecycle. Actions, as needed.
64
65. Other Differences
Struts 1 Struts 2
Action Action
ActionForm Action or POJO
ActionForward Result
struts-config.xml struts.xml
ActionServlet FilterDispatcher
RequestProcessor Interceptors
validation.xml Action-validation.xml
65
67. Scenario(s)
2 use cases
Employee Attributes
View list of Employees
Add an Employee • Name
• Age
• Date of Birth
• Gender
• Country
67
68. Pre-requisite
Need to have a following download and installed
Java EE 1.5
Java SDK 1.7
Tomcat 7.0
Struts 2 libraries
Database (like MySQL)
Development environment (Eclipse)
68
69. Scenario 1 – View list of employees
In the scenario, we will explore the following additional
components
Controller
Actions
Results
69
70. Scenario 1 – View list of employees – Step 1
Open Eclipse and create an dynamic
web application project
Add the struts jars to the class path
Configuring the controller in the
web.xml
70
71. Scenario 1 – View list of employees – Step 2a
Next, we will define
the Action class
71
72. Scenario 1 – View list of employees – Step 2b
Next, we will define
the Action
72
73. Scenario 1 – View list of employees – Step 3
Next, we will map the
Action to the result
in the struts.xml
73
74. Scenario 1 – View list of employees – Step 4
Next, we will see
the viewEmp.jsp
that was
configured as the
dispatcher jsp
74
75. Scenario 1 – View list of employees – Step 5
This completes all the steps in the scenario
We compile and deploy the war file in the tomcat
We hit the URL
http://localhost:8080/Struts2Application/view.action
75
76. Scenario 2 – Add an Employee
In the scenario, we will explore the following additional
components
Validations
Field
Non-Field
Interceptors
76
77. Scenario 2 – Add an Employee – Step 1
Define the JSP page
– addEmployee.jsp
with the struts 2
tags
77
78. Scenario 2 – Add an Employee – Step 2
Define the Action
class –
AddEmployeeAction.java
78
79. Scenario 2 – Add an Employee – Step 2
Define the Action
class –
AddEmployeeAction.java
79
80. Scenario 2 – Add an Employee – Step 3
Next, lets define validation for
the following fields as
Age
Mandatory Field
Value should be between 18
and 60
Date of birth
Mandatory Field
Date format should be DD-
MM-YYYY
Name
Mandatory field
80
81. Scenario 2 – Add an Employee – Step 3
Next, lets define validation for
the following fields as
Age
Mandatory Field
Value should be between 18
and 60
Date of birth
Mandatory Field
Date format should be DD-
MM-YYYY
Name
Mandatory field
81
82. Scenario 2 – Add an Employee – Step 3
Next, lets define validation for
the following fields as
Age
Mandatory Field
Value should be between 18
and 60
Date of birth
Mandatory Field
Date format should be DD-
MM-YYYY
Name
Mandatory field
82
83. Scenario 2 – Add an Employee – Step 3
Next, lets define validation for
the following fields as
Age
Mandatory Field
Value should be between 18
and 60
Date of birth
Mandatory Field
Date format should be DD-
MM-YYYY
Name
Mandatory field
83
84. Scenario 2 – Add an Employee – Step 3
Next, lets define validation for
the following fields as
Age
Mandatory Field
Value should be between 18
and 60
Date of birth
Mandatory Field
Date format should be DD-
MM-YYYY
Name
Mandatory field
84
85. Scenario 2 – Add an Employee – Step 4
Next , we will see
the changes in the
struts.xml
85
86. Scenario 2 – Add an Employee – Step 4
Next , we will see
the changes in the
struts.xml
86
87. Scenario 2 – Add an Employee – Step 5
Where is the
validator
interceptor
defined?
87
88. Scenario 2 – Add an Employee – Step 5
How do I
override the
default ?
88
89. Scenario 2 – Add an Employee – Step 5
How do I
override the
default ?
89
90. Scenario 2 – Add an Employee – Step 5
How do I
override the
default ?
90
91. Scenario 2 – Add an Employee – Step 5
How do I
override the
default ?
91
92. Scenario 2 – Add an Employee – Step 6
Coming back to
the Action class
92
93. Scenario 2 – Add an Employee – Step 7
So overall, we added or changed the following files
Added
AddEmployeeAction.java
AddEmployeeAction-validation.xml
AddEmployeeAction.properties
addEmployee.jsp
Changed
Struts.xml
93
94. Scenario 2 – Add an Employee – Step 8
This completes all the steps in the scenario
We compile and deploy the war file in the tomcat
We hit the URL
http://localhost:8080/Struts2Application/addEmp.action
94
95. Scenario 2 – Add an Employee – Step 9
Press Enter
95
96. Scenario 2 – Add an Employee – Step 9
Press Enter
96
97. Conclusion
This concludes the programming demo
Refer to struts 2 documentation for more in-depth
details on each of the components
97