SlideShare a Scribd company logo
Introducing Struts 2 JaMU 07.02 – February 24, 2007 Thomas Wiradikusuma (thomas@wiradikusuma.com) Java User Group Indonesia
Struts 2 defined An elegant, extensible framework for building enterprise-ready Java web applications An MVC web framework Action-based Successor of the famous Struts framework (and WebWork 2, technically speaking)
Sweet spots Simple architecture Interceptors, Actions, Results from pluggable ObjectFactory Controller-based or page-based navigation Support for POJO, Annotation, JSF Cool, customizable tag library with OGNL support Value stack Spring as default inversion of control container QuickStart Built-in Ajax support Many convention-over-configuration and sensible defaults Easier to test (out of container) Brings the best of Struts 1 and WebWork 2, including their fanatic followers ;-)
Architecture Request arrives FilterDispatcher finds appropriate Action Interceptors get applied Method in Action executes (usually doing “core” stuff) Result renders output
Architecture, cont’d
ActionMapper Provide a mapping between HTTP requests and action invocation requests and vice-versa Default implementation uses standard *.[ext] (usually &quot;action&quot;) pattern. Extension is defined in Struts configuration key struts.action.exection. Prefixes: method:  <a:submit name=“method:bar” value=“Bar”/>   action:  <a:submit name=“action:foo” value=“Foo”/> redirect:  <a:submit name=“redirect:http://www.google.com” value=“Google”/> redirect-action:  <a:submit name=“redirect-action:foo” value=“Foo”/>
Interceptors <interceptor-stack name=&quot;xaStack&quot;> <interceptor-ref name=&quot;thisWillRunFirstInterceptor&quot;/> <interceptor-ref name=&quot;thisWillRunNextInterceptor&quot;/> <interceptor-ref name=&quot;followedByThisInterceptor&quot;/> <interceptor-ref name=&quot;thisWillRunLastInterceptor&quot;/> </interceptor-stack> thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor
Interceptors, 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 Description Name Interceptor
Actions All actions may implement this interface, which exposes the execute() method. However, as of XWork 1.1, this is not required and is only here to assist users. You are free to create POJOs that honor the same contract defined by this interface without actually implementing the interface. ActionSupport class provides a default implementation for the most common actions.
Results Used for Velocity integration Velocity And many more… Used for Action Chaining Chain Used to stream an InputStream back to the browser (usually for file downloads) Stream Used to redirect to another action mapping Redirect Action Used to redirect to another URL (web resource)  Redirect Used for web resource integration, including JSP integration Dispatcher Usage Result
Type conversion Everything is String in HTTP Built-in: boolean, char, numeric types, dates, arrays, collections ClassName-conversion.properties: foo = package.FooConverter Globally in struts-conversion.properties in the root of your class path (typically WEB-INF/classes)  package.Foo = package.FooConverter Extend StrutsTypeConverter  to simplify creating a converter Throw TypeConversionException when conversion exception happens. Information will be displayed as specified in Struts configuration struts.default.invalid.fieldvalue
Localization Resource bundles are searched in the following order: ActionClass.properties  BaseClass.properties (all the way to Object.properties)  Interface.properties (every interface and sub-interface)  ModelDriven's model (if implements ModelDriven), for the model object repeat from 1  package.properties (of the directory where class is located and every parent directory all the way to the root directory)  search up the i18n message key hierarchy itself  global resource properties  Accessing key: getText: <s:property value=&quot;getText('some.key')&quot; />  text tag: <s:text name=&quot;some.key&quot; />  I18n tag to push an arbitrary resource bundle on to the value stack: <s:i18n name=&quot;some.package.bundle&quot; > <s:text name=&quot;some.key&quot; /> </s:i18n>
Configuration files Override the default Velocity configuration /WEB-INF/classes/  Yes velocity.properties Optional configuration files for plug-ins in the same format as struts.xml. Root of a plug-in JAR  Yes struts-plugin.xml  Default macros referenced by velocity.properties /WEB-INF/classes/  Yes struts-default.vm Default configuration provided by Struts /WEB-INF/lib/struts2-core.jar  Yes struts-default.xml Framework properties /WEB-INF/classes/  Yes struts.properties Main configuration, contains result/view types, action mappings, interceptors, and so forth /WEB-INF/classes/  Yes struts.xml Deployment descriptor /WEB-INF/  No web.xml Purpose  Location Optional? File
Taglib <% User user = ActionContext.getContext() %> <form action=&quot;Profile_update.action&quot; method=&quot;post&quot;> <table> <tr> <td> align=&quot;right&quot;><label>First name:</label></td> <td><input type=&quot;text&quot; name=&quot;user.firstname&quot; value=&quot;<%=user.getFirstname() %> /></td> </tr> <tr> <td> <input type=&quot;radio&quot; name=&quot;user.gender&quot; value=&quot;0&quot; id=&quot;user.gender0&quot;  <% if (user.getGender()==0) { %> checked=&quot;checked&quot; %> } %> /> <label for=&quot;user.gender0&quot;>Female</label> ... Without taglib (JSP): <s:actionerror/> <s:form action=&quot;Profile_update&quot; validate=&quot;true&quot;> <s:textfield label=&quot;Username&quot; name=&quot;username&quot;/> <s:password label=&quot;Password&quot; name=&quot;password&quot;/> <s:password label=&quot;(Repeat) Password&quot; name=&quot;password2&quot;/> <s:textfield label=&quot;Full Name&quot; name=&quot;fullName&quot;/> <s:textfield label=&quot;From Address&quot; name=&quot;fromAddress&quot;/> <s:textfield label=&quot;Reply To Address&quot; name=&quot;replyToAddress&quot;/> <s:submit value=&quot;Save&quot; name=&quot;Save&quot;/> <s:submit action=&quot;Register_cancel&quot; value=&quot;Cancel&quot; name=&quot;Cancel&quot; onclick=&quot;form.onsubmit=null&quot;/> </s:form> With taglib (JSP):
Taglib, cont’d <%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %>  Tags category: Control Data UI (form and non-form) Ajax
Servlet/JSP scoped object Application <s:property value=&quot;%{#application.foo}&quot; />   Session <s:property value=&quot;%{#session.foo}&quot; />   Request <s:property value=&quot;%{#request.foo}&quot; />   Parameter <s:property value=&quot;%{#parameter.foo}&quot; />   Context <s:property value=&quot;%{#foo}&quot; />
OGNL Object Graph Navigation Language More powerful than JSTL EL
Spring integration By default, the framework will at least try to use Spring to create all its objects. If the object cannot be created by Spring, then the framework will create the object itself.
Testing Direct Action invocation Out of container testing Testing Interceptors and/or Results
Struts 1 to Struts 2 Despite the similar name (Struts), migrating from Struts 1 is harder than migrating from WebWork 2. struts.xml struts-config.xml Action or POJO ActionForm Action or POJO Action (singleton) {action}-validation.xml validation.xml Result ActionForward Interceptors RequestProcessor FilterDispatcher ActionServlet Struts 2 Struts 1
WebWork 2 to Struts 2 Pretty much the same, only naming/namespace changes. <s:*/> <ww:*/> struts.xml xwork.xml struts.properties webwork.properties com.opensymphony.xwork2.* com.opensymphony.xwork.* “ struts” “ webwork” org.apache.struts2.* com.opensymphony.webwork.* Struts 2 WebWork 2
Requirements Servlet API 2.4 JSP API 2.0 Java 5 (or 1.4 with Retroweaver)
Integration with open source libraries Spring 2.0 Velocity Freemarker JasperReports DWR Apache Pluto dojo and many more…
Not discussed Annotation support JSF, Ajax support Plug-ins QuickStart Validation Value stack Wildcard mappings Zero configuration
Where to go from here Struts (1 and 2) http://struts.apache.org AppFuse 2 http://www.appfuse.org

More Related Content

PPT
PPT
Struts 2 Overview
PDF
Struts2
PPTX
Apache Struts 2 Framework
PPT
Struts2
PPTX
Struts 2
PDF
Introduction to struts
Struts 2 Overview
Struts2
Apache Struts 2 Framework
Struts2
Struts 2
Introduction to struts

What's hot (20)

PPT
Struts Ppt 1
PDF
Struts2 notes
PPTX
Struts 1
PPTX
01 introduction to struts2
PDF
Struts Basics
PPT
Struts,Jsp,Servlet
PPT
Struts2
DOCX
Struts ppt 1
PDF
Step by Step Guide for building a simple Struts Application
PDF
Struts An Open-source Architecture for Web Applications
PPT
Struts
PPT
Struts course material
PPTX
Skillwise Struts.x
PPT
Struts2 course chapter 1: Evolution of Web Applications
PPTX
DOCX
TY.BSc.IT Java QB U1
DOCX
TY.BSc.IT Java QB U6
PPT
Struts Introduction Course
DOCX
TY.BSc.IT Java QB U3
PDF
Struts notes
Struts Ppt 1
Struts2 notes
Struts 1
01 introduction to struts2
Struts Basics
Struts,Jsp,Servlet
Struts2
Struts ppt 1
Step by Step Guide for building a simple Struts Application
Struts An Open-source Architecture for Web Applications
Struts
Struts course material
Skillwise Struts.x
Struts2 course chapter 1: Evolution of Web Applications
TY.BSc.IT Java QB U1
TY.BSc.IT Java QB U6
Struts Introduction Course
TY.BSc.IT Java QB U3
Struts notes
Ad

Viewers also liked (9)

PPTX
ERP Implementation: Avoiding Common Pitfalls
PDF
Rapid Deployment of ERP solutions using Lean & Agile Methods
PDF
Top 10 Reasons to Choose Oracle ERP Cloud Financials
PDF
12. Managing Risk Factors In Erp Implementation And Design
PDF
Hidden cost of erp customization
PPTX
Risk In Erp Implementation Projects
PPT
ERP-Case Study- Changes before and after implementing ERP in a company
PPTX
Air India - ERP Implementation Case Study
PDF
Implementing Cloud Financials
ERP Implementation: Avoiding Common Pitfalls
Rapid Deployment of ERP solutions using Lean & Agile Methods
Top 10 Reasons to Choose Oracle ERP Cloud Financials
12. Managing Risk Factors In Erp Implementation And Design
Hidden cost of erp customization
Risk In Erp Implementation Projects
ERP-Case Study- Changes before and after implementing ERP in a company
Air India - ERP Implementation Case Study
Implementing Cloud Financials
Ad

Similar to Introducing Struts 2 (20)

PPT
Struts2 in a nutshell
PPT
Struts2.x
PPTX
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
PPT
Struts2.0basic
PPS
Struts Java I I Lecture 8
PPTX
struts unit best pdf for struts java.pptx
DOCX
Struts notes
PDF
Struts 2 In Action 1st Edition Don Brown Chad Michael Davis Scott Stanlick
PDF
Migrating from Struts 1 to Struts 2
PPT
Struts Overview
PDF
Łukasz Lenart "How secure your web framework is? Based on Apache Struts 2"
PPT
D22 portlet development with open source frameworks
PPT
D22 Portlet Development With Open Source Frameworks
PPT
Ibm
PDF
Struts2 tutorial
PDF
Struts2 tutorial
PPT
Struts2 course chapter 2: installation and configuration
PDF
important struts interview questions
PPT
Strutsjspservlet
PPT
Strutsjspservlet
Struts2 in a nutshell
Struts2.x
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
Struts2.0basic
Struts Java I I Lecture 8
struts unit best pdf for struts java.pptx
Struts notes
Struts 2 In Action 1st Edition Don Brown Chad Michael Davis Scott Stanlick
Migrating from Struts 1 to Struts 2
Struts Overview
Łukasz Lenart "How secure your web framework is? Based on Apache Struts 2"
D22 portlet development with open source frameworks
D22 Portlet Development With Open Source Frameworks
Ibm
Struts2 tutorial
Struts2 tutorial
Struts2 course chapter 2: installation and configuration
important struts interview questions
Strutsjspservlet
Strutsjspservlet

More from wiradikusuma (9)

KEY
Practical OOP In Java
ODP
Open Source And Java
ODP
Open Source is Not An Alternative, It is The Solution
PPT
Design Pattern
PPT
Spring 2.1 Exposed
PPT
A Taste of Java ME
PPT
Subversion
PPT
Spring and DWR
PPT
OOP in Java
Practical OOP In Java
Open Source And Java
Open Source is Not An Alternative, It is The Solution
Design Pattern
Spring 2.1 Exposed
A Taste of Java ME
Subversion
Spring and DWR
OOP in Java

Recently uploaded (20)

PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Encapsulation theory and applications.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
A Presentation on Artificial Intelligence
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Cloud computing and distributed systems.
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPT
Teaching material agriculture food technology
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Encapsulation theory and applications.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
A Presentation on Artificial Intelligence
“AI and Expert System Decision Support & Business Intelligence Systems”
Chapter 3 Spatial Domain Image Processing.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Cloud computing and distributed systems.
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Teaching material agriculture food technology
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Machine learning based COVID-19 study performance prediction
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Advanced methodologies resolving dimensionality complications for autism neur...
Dropbox Q2 2025 Financial Results & Investor Presentation
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Per capita expenditure prediction using model stacking based on satellite ima...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Review of recent advances in non-invasive hemoglobin estimation

Introducing Struts 2

  • 1. Introducing Struts 2 JaMU 07.02 – February 24, 2007 Thomas Wiradikusuma (thomas@wiradikusuma.com) Java User Group Indonesia
  • 2. Struts 2 defined An elegant, extensible framework for building enterprise-ready Java web applications An MVC web framework Action-based Successor of the famous Struts framework (and WebWork 2, technically speaking)
  • 3. Sweet spots Simple architecture Interceptors, Actions, Results from pluggable ObjectFactory Controller-based or page-based navigation Support for POJO, Annotation, JSF Cool, customizable tag library with OGNL support Value stack Spring as default inversion of control container QuickStart Built-in Ajax support Many convention-over-configuration and sensible defaults Easier to test (out of container) Brings the best of Struts 1 and WebWork 2, including their fanatic followers ;-)
  • 4. Architecture Request arrives FilterDispatcher finds appropriate Action Interceptors get applied Method in Action executes (usually doing “core” stuff) Result renders output
  • 6. ActionMapper Provide a mapping between HTTP requests and action invocation requests and vice-versa Default implementation uses standard *.[ext] (usually &quot;action&quot;) pattern. Extension is defined in Struts configuration key struts.action.exection. Prefixes: method: <a:submit name=“method:bar” value=“Bar”/> action: <a:submit name=“action:foo” value=“Foo”/> redirect: <a:submit name=“redirect:http://www.google.com” value=“Google”/> redirect-action: <a:submit name=“redirect-action:foo” value=“Foo”/>
  • 7. Interceptors <interceptor-stack name=&quot;xaStack&quot;> <interceptor-ref name=&quot;thisWillRunFirstInterceptor&quot;/> <interceptor-ref name=&quot;thisWillRunNextInterceptor&quot;/> <interceptor-ref name=&quot;followedByThisInterceptor&quot;/> <interceptor-ref name=&quot;thisWillRunLastInterceptor&quot;/> </interceptor-stack> thisWillRunFirstInterceptor thisWillRunNextInterceptor followedByThisInterceptor thisWillRunLastInterceptor MyAction1 MyAction2 (chain) MyPreResultListener MyResult (result) thisWillRunLastInterceptor followedByThisInterceptor thisWillRunNextInterceptor thisWillRunFirstInterceptor
  • 8. Interceptors, 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 Description Name Interceptor
  • 9. Actions All actions may implement this interface, which exposes the execute() method. However, as of XWork 1.1, this is not required and is only here to assist users. You are free to create POJOs that honor the same contract defined by this interface without actually implementing the interface. ActionSupport class provides a default implementation for the most common actions.
  • 10. Results Used for Velocity integration Velocity And many more… Used for Action Chaining Chain Used to stream an InputStream back to the browser (usually for file downloads) Stream Used to redirect to another action mapping Redirect Action Used to redirect to another URL (web resource) Redirect Used for web resource integration, including JSP integration Dispatcher Usage Result
  • 11. Type conversion Everything is String in HTTP Built-in: boolean, char, numeric types, dates, arrays, collections ClassName-conversion.properties: foo = package.FooConverter Globally in struts-conversion.properties in the root of your class path (typically WEB-INF/classes) package.Foo = package.FooConverter Extend StrutsTypeConverter to simplify creating a converter Throw TypeConversionException when conversion exception happens. Information will be displayed as specified in Struts configuration struts.default.invalid.fieldvalue
  • 12. Localization Resource bundles are searched in the following order: ActionClass.properties BaseClass.properties (all the way to Object.properties) Interface.properties (every interface and sub-interface) ModelDriven's model (if implements ModelDriven), for the model object repeat from 1 package.properties (of the directory where class is located and every parent directory all the way to the root directory) search up the i18n message key hierarchy itself global resource properties Accessing key: getText: <s:property value=&quot;getText('some.key')&quot; /> text tag: <s:text name=&quot;some.key&quot; /> I18n tag to push an arbitrary resource bundle on to the value stack: <s:i18n name=&quot;some.package.bundle&quot; > <s:text name=&quot;some.key&quot; /> </s:i18n>
  • 13. Configuration files Override the default Velocity configuration /WEB-INF/classes/ Yes velocity.properties Optional configuration files for plug-ins in the same format as struts.xml. Root of a plug-in JAR Yes struts-plugin.xml Default macros referenced by velocity.properties /WEB-INF/classes/ Yes struts-default.vm Default configuration provided by Struts /WEB-INF/lib/struts2-core.jar Yes struts-default.xml Framework properties /WEB-INF/classes/ Yes struts.properties Main configuration, contains result/view types, action mappings, interceptors, and so forth /WEB-INF/classes/ Yes struts.xml Deployment descriptor /WEB-INF/ No web.xml Purpose Location Optional? File
  • 14. Taglib <% User user = ActionContext.getContext() %> <form action=&quot;Profile_update.action&quot; method=&quot;post&quot;> <table> <tr> <td> align=&quot;right&quot;><label>First name:</label></td> <td><input type=&quot;text&quot; name=&quot;user.firstname&quot; value=&quot;<%=user.getFirstname() %> /></td> </tr> <tr> <td> <input type=&quot;radio&quot; name=&quot;user.gender&quot; value=&quot;0&quot; id=&quot;user.gender0&quot; <% if (user.getGender()==0) { %> checked=&quot;checked&quot; %> } %> /> <label for=&quot;user.gender0&quot;>Female</label> ... Without taglib (JSP): <s:actionerror/> <s:form action=&quot;Profile_update&quot; validate=&quot;true&quot;> <s:textfield label=&quot;Username&quot; name=&quot;username&quot;/> <s:password label=&quot;Password&quot; name=&quot;password&quot;/> <s:password label=&quot;(Repeat) Password&quot; name=&quot;password2&quot;/> <s:textfield label=&quot;Full Name&quot; name=&quot;fullName&quot;/> <s:textfield label=&quot;From Address&quot; name=&quot;fromAddress&quot;/> <s:textfield label=&quot;Reply To Address&quot; name=&quot;replyToAddress&quot;/> <s:submit value=&quot;Save&quot; name=&quot;Save&quot;/> <s:submit action=&quot;Register_cancel&quot; value=&quot;Cancel&quot; name=&quot;Cancel&quot; onclick=&quot;form.onsubmit=null&quot;/> </s:form> With taglib (JSP):
  • 15. Taglib, cont’d <%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %> Tags category: Control Data UI (form and non-form) Ajax
  • 16. Servlet/JSP scoped object Application <s:property value=&quot;%{#application.foo}&quot; /> Session <s:property value=&quot;%{#session.foo}&quot; /> Request <s:property value=&quot;%{#request.foo}&quot; /> Parameter <s:property value=&quot;%{#parameter.foo}&quot; /> Context <s:property value=&quot;%{#foo}&quot; />
  • 17. OGNL Object Graph Navigation Language More powerful than JSTL EL
  • 18. Spring integration By default, the framework will at least try to use Spring to create all its objects. If the object cannot be created by Spring, then the framework will create the object itself.
  • 19. Testing Direct Action invocation Out of container testing Testing Interceptors and/or Results
  • 20. Struts 1 to Struts 2 Despite the similar name (Struts), migrating from Struts 1 is harder than migrating from WebWork 2. struts.xml struts-config.xml Action or POJO ActionForm Action or POJO Action (singleton) {action}-validation.xml validation.xml Result ActionForward Interceptors RequestProcessor FilterDispatcher ActionServlet Struts 2 Struts 1
  • 21. WebWork 2 to Struts 2 Pretty much the same, only naming/namespace changes. <s:*/> <ww:*/> struts.xml xwork.xml struts.properties webwork.properties com.opensymphony.xwork2.* com.opensymphony.xwork.* “ struts” “ webwork” org.apache.struts2.* com.opensymphony.webwork.* Struts 2 WebWork 2
  • 22. Requirements Servlet API 2.4 JSP API 2.0 Java 5 (or 1.4 with Retroweaver)
  • 23. Integration with open source libraries Spring 2.0 Velocity Freemarker JasperReports DWR Apache Pluto dojo and many more…
  • 24. Not discussed Annotation support JSF, Ajax support Plug-ins QuickStart Validation Value stack Wildcard mappings Zero configuration
  • 25. Where to go from here Struts (1 and 2) http://struts.apache.org AppFuse 2 http://www.appfuse.org