Introducing Introducing Struts 2Struts 2JaMU 07.02 – February 24, 2007JaMU 07.02 – February 24, 2007
Thomas WiradikusumaThomas Wiradikusuma([email protected])([email protected])
Struts 2 definedStruts 2 defined
An elegant, extensible framework for An elegant, extensible framework for building enterprise-ready Java web building enterprise-ready Java web applicationsapplications
An MVC web frameworkAn MVC web framework Action-basedAction-based Successor of the famous Struts Successor of the famous Struts
framework (and WebWork 2, technically framework (and WebWork 2, technically speaking)speaking)
Sweet spotsSweet spots Simple architectureSimple architecture Interceptors, Actions, Results from pluggable ObjectFactoryInterceptors, Actions, Results from pluggable ObjectFactory Controller-based or page-based navigationController-based or page-based navigation Support for POJO, Annotation, JSFSupport for POJO, Annotation, JSF Cool, customizable tag library with OGNL supportCool, customizable tag library with OGNL support Value stackValue stack Spring as default inversion of control containerSpring as default inversion of control container QuickStartQuickStart Built-in Ajax supportBuilt-in Ajax support Many convention-over-configuration and sensible defaultsMany convention-over-configuration and sensible defaults Easier to test (out of container)Easier to test (out of container) Brings the best of Struts 1 and WebWork 2, including their Brings the best of Struts 1 and WebWork 2, including their
fanatic followers ;-)fanatic followers ;-)
ArchitectureArchitecture
Request arrivesRequest arrives FilterDispatcher finds FilterDispatcher finds
appropriate Actionappropriate Action Interceptors get Interceptors get
appliedapplied Method in Action Method in Action
executes (usually executes (usually doing “core” stuff)doing “core” stuff)
Result renders outputResult renders output
Architecture, cont’dArchitecture, cont’d
ActionMapperActionMapper
Provide a mapping between HTTP requests Provide a mapping between HTTP requests and action invocation requests and vice-versaand action invocation requests and vice-versa
Default implementation uses standard *.[ext] Default implementation uses standard *.[ext] (usually "action") pattern. Extension is defined (usually "action") pattern. Extension is defined in Struts configuration key in Struts configuration key struts.action.exection. Prefixes:struts.action.exection. Prefixes: method: method: <a:submit name=“method:bar” value=“Bar”/><a:submit name=“method:bar” value=“Bar”/> action: action: <a:submit name=“action:foo” value=“Foo”/><a:submit name=“action:foo” value=“Foo”/>
redirect: redirect: <a:submit name=“redirect:http://www.google.com” <a:submit name=“redirect:http://www.google.com” value=“Google”/>value=“Google”/>
redirect-action: redirect-action: <a:submit name=“redirect-action:foo” value=“Foo”/><a:submit name=“redirect-action:foo” value=“Foo”/>
InterceptorsInterceptors<interceptor-stack name="xaStack"> <interceptor-ref name="thisWillRunFirstInterceptor"/> <interceptor-ref name="thisWillRunNextInterceptor"/> <interceptor-ref name="followedByThisInterceptor"/> <interceptor-ref name="thisWillRunLastInterceptor"/></interceptor-stack>
thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptorthisWillRunFirstInterceptor
Interceptors, cont’dInterceptors, cont’d
Checks for valid token presence in Action, prevents duplicate form submission.
token Token
And many more…
Action will only be executed if the user has the correct JAAS role.roles Roles
If the Action implements Preparable, calls its prepare method. prepare Prepare
Sets the request parameters onto the Action. params Parameters
Executes the Action in the background and then sends the user off to an intermediate waiting page.
execAndWait Execute and Wait
Adds automatic checkbox handling code that detect an unchecked checkbox and add it as a parameter with a default (usually 'false') value. Uses a specially named hidden field to detect unsubmitted checkboxes.
checkbox Checkbox
DescriptionNameInterceptor
ActionsActions
All actions may implement this interface, which All actions may implement this interface, which exposes the execute() method. However, as of exposes the execute() method. However, as of XWork 1.1, this is not required and is only here XWork 1.1, this is not required and is only here to assist users. You are free to create POJOs to assist users. You are free to create POJOs that honor the same contract defined by this that honor the same contract defined by this interface without actually implementing the interface without actually implementing the interface.interface.
ActionSupport class provides a default ActionSupport class provides a default implementation for the most common actions. implementation for the most common actions.
ResultsResults
Used for Velocity integrationVelocity
And many more…
Used for Action ChainingChain
Used to stream an InputStream back to the browser (usually for file downloads)
Stream
Used to redirect to another action mappingRedirect Action
Used to redirect to another URL (web resource) Redirect
Used for web resource integration, including JSP integration
Dispatcher
UsageResult
Type conversionType conversion Everything is String in HTTPEverything is String in HTTP Built-in: boolean, char, numeric types, dates, arrays, collectionsBuilt-in: boolean, char, numeric types, dates, arrays, collections ClassName-conversion.properties:ClassName-conversion.properties:
foo = package.FooConverterfoo = package.FooConverter Globally in struts-conversion.properties in the root of your class Globally in struts-conversion.properties in the root of your class
path (typically WEB-INF/classes) path (typically WEB-INF/classes) package.Foo = package.FooConverterpackage.Foo = package.FooConverter
Extend StrutsTypeConverter to simplify creating a converterExtend StrutsTypeConverter to simplify creating a converter Throw TypeConversionException when conversion exception Throw TypeConversionException when conversion exception
happens. Information will be displayed as specified in Struts happens. Information will be displayed as specified in Struts configuration struts.default.invalid.fieldvalueconfiguration struts.default.invalid.fieldvalue
LocalizationLocalization Resource bundles are searched in the following order:Resource bundles are searched in the following order:
ActionClass.properties ActionClass.properties BaseClass.properties (all the way to Object.properties) BaseClass.properties (all the way to Object.properties) Interface.properties (every interface and sub-interface) Interface.properties (every interface and sub-interface) ModelDriven's model (if implements ModelDriven), for the model object repeat ModelDriven's model (if implements ModelDriven), for the model object repeat
from 1 from 1 package.properties (of the directory where class is located and every parent package.properties (of the directory where class is located and every parent
directory all the way to the root directory) directory all the way to the root directory) search up the i18n message key hierarchy itself search up the i18n message key hierarchy itself global resource properties global resource properties
Accessing key:Accessing key: getText: <s:property value="getText('some.key')" /> getText: <s:property value="getText('some.key')" /> text tag: <s:text name="some.key" /> text tag: <s:text name="some.key" /> I18n tag to push an arbitrary resource bundle on to the value stack:I18n tag to push an arbitrary resource bundle on to the value stack:
<s:i18n name="some.package.bundle" ><s:i18n name="some.package.bundle" > <s:text name="some.key" /><s:text name="some.key" />
</s:i18n></s:i18n>
Configuration filesConfiguration files
Override the default Velocity configuration
/WEB-INF/classes/ Yesvelocity.properties
Optional configuration files for plug-ins in the same format as struts.xml.
Root of a plug-in JAR Yesstruts-plugin.xml
Default macros referenced by velocity.properties
/WEB-INF/classes/ Yesstruts-default.vm
Default configuration provided by Struts/WEB-INF/lib/struts2-core.jar Yesstruts-default.xml
Framework properties/WEB-INF/classes/ Yesstruts.properties
Main configuration, contains result/view types, action mappings, interceptors, and so forth
/WEB-INF/classes/ Yesstruts.xml
Deployment descriptor/WEB-INF/ Noweb.xml
Purpose LocationOptional?
File
TaglibTaglib<% User user = ActionContext.getContext() %><form action="Profile_update.action" method="post"> <table> <tr> <td> align="right"><label>First name:</label></td> <td><input type="text" name="user.firstname" value="<%=user.getFirstname() %> /></td> </tr> <tr> <td> <input type="radio" name="user.gender" value="0" id="user.gender0" <% if (user.getGender()==0) { %> checked="checked" %> } %> /> <label for="user.gender0">Female</label>...
Without taglib (JSP):
<s:actionerror/><s:form action="Profile_update" validate="true"> <s:textfield label="Username" name="username"/> <s:password label="Password" name="password"/> <s:password label="(Repeat) Password" name="password2"/> <s:textfield label="Full Name" name="fullName"/> <s:textfield label="From Address" name="fromAddress"/> <s:textfield label="Reply To Address" name="replyToAddress"/> <s:submit value="Save" name="Save"/> <s:submit action="Register_cancel" value="Cancel" name="Cancel" onclick="form.onsubmit=null"/></s:form>
With taglib (JSP):
Taglib, cont’dTaglib, cont’d
<%@ taglib prefix="s" uri="/struts-tags" %> <%@ taglib prefix="s" uri="/struts-tags" %> Tags category:Tags category:
ControlControl DataData UI (form and non-form)UI (form and non-form) AjaxAjax
Servlet/JSP scoped Servlet/JSP scoped objectobject ApplicationApplication
<s:property value="%{#application.foo}" /><s:property value="%{#application.foo}" /> SessionSession
<s:property value="%{#session.foo}" /><s:property value="%{#session.foo}" /> RequestRequest
<s:property value="%{#request.foo}" /><s:property value="%{#request.foo}" /> ParameterParameter
<s:property value="%{#parameter.foo}" /><s:property value="%{#parameter.foo}" /> ContextContext
<s:property value="%{#foo}" /><s:property value="%{#foo}" />
OGNLOGNL
Object Graph Navigation LanguageObject Graph Navigation Language More powerful than JSTL ELMore powerful than JSTL EL
Spring integrationSpring integration
By default, the framework will at least try By default, the framework will at least try to use Spring to create all its objects. If to use Spring to create all its objects. If the object cannot be created by Spring, the object cannot be created by Spring, then the framework will create the object then the framework will create the object itself. itself.
TestingTesting
Direct Action invocationDirect Action invocation Out of container testingOut of container testing Testing Interceptors and/or ResultsTesting Interceptors and/or Results
Struts 1 to Struts 2Struts 1 to Struts 2
struts.xmlstruts-config.xml
Action or POJOActionForm
Action or POJOAction (singleton)
{action}-validation.xmlvalidation.xml
ResultActionForward
InterceptorsRequestProcessor
FilterDispatcherActionServlet
Struts 2Struts 1
Despite the similar name (Struts), migrating from Struts 1 is harder than migrating from WebWork 2.
WebWork 2 to Struts 2WebWork 2 to Struts 2
<s:*/><ww:*/>
struts.xmlxwork.xml
struts.propertieswebwork.properties
com.opensymphony.xwork2.*com.opensymphony.xwork.*
“struts”“webwork”
org.apache.struts2.*com.opensymphony.webwork.*
Struts 2WebWork 2
Pretty much the same, only naming/namespace changes.
RequirementsRequirements
Servlet API 2.4Servlet API 2.4 JSP API 2.0JSP API 2.0 Java 5 (or 1.4 with Retroweaver)Java 5 (or 1.4 with Retroweaver)
Integration with open Integration with open source librariessource libraries
Spring 2.0Spring 2.0 VelocityVelocity FreemarkerFreemarker JasperReportsJasperReports DWRDWR Apache PlutoApache Pluto dojodojo and many more…and many more…
Not discussedNot discussed
Annotation supportAnnotation support JSF, Ajax supportJSF, Ajax support Plug-insPlug-ins QuickStartQuickStart ValidationValidation Value stackValue stack Wildcard mappingsWildcard mappings Zero configurationZero configuration
Where to go from hereWhere to go from here
Struts (1 and 2)Struts (1 and 2)http://struts.apache.orghttp://struts.apache.org
AppFuse 2AppFuse 2http://www.appfuse.orghttp://www.appfuse.org