Your SlideShare is downloading. ×
0
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Struts2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Struts2

12,200

Published on

This is a presentation I gave recently at the Apache conference

This is a presentation I gave recently at the Apache conference

Published in: Technology, Education
0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
12,200
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
934
Comments
0
Likes
12
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • I expect student has a fair understanding of Struts Classic
  • Transcript

    • 1. For Struts Developers
    • 2. Me <ul><li>Scott Stanlick </li></ul><ul><ul><li>Drummer </li></ul></ul><ul><ul><li>Techie </li></ul></ul><ul><ul><li>Instructor </li></ul></ul><ul><ul><li>Connoisseur of cereal malt beverages </li></ul></ul>
    • 3. Agenda <ul><li>Hello Struts 2 </li></ul><ul><li>Action/Interceptor/Result </li></ul><ul><li>Configuration </li></ul><ul><li>OGNL/Value Stack </li></ul><ul><li>Tag Libraries </li></ul><ul><li>Business Validation </li></ul><ul><li>Plug-ins </li></ul><ul><li>Wrap up </li></ul>
    • 4. Hello Struts 2 The History
    • 5. What is Struts 2? <ul><li>Not Struts 1.x! </li></ul><ul><li>EE5 Web Framework </li></ul><ul><li>Originally OpenSymphony WebWork </li></ul><ul><li>WebWork + Struts + Apache Incubator </li></ul><ul><ul><li>Struts 2 was hatched in ‘07 </li></ul></ul>
    • 6. Built Specifically For… <ul><li>Developer Productivity </li></ul><ul><ul><li>Simple HTTP-free code </li></ul></ul><ul><ul><li>Easy Spring integration </li></ul></ul><ul><ul><li>Reusable UI templates </li></ul></ul><ul><ul><li>Plug-in architecture </li></ul></ul><ul><ul><li>Crazy cool type conversions </li></ul></ul><ul><ul><li>Rich validation </li></ul></ul><ul><ul><li>Easy to test </li></ul></ul><ul><ul><li>And so much more! </li></ul></ul>
    • 7. Configuration Styles <ul><li>Packaged actions (namespace) </li></ul><ul><li>Package inheritance </li></ul><ul><li>Wildcard mappings </li></ul><ul><li>Generic actions </li></ul><ul><li>Annotations </li></ul><ul><li>Ruby-On-Rails Rest-style mappings </li></ul><ul><ul><li>Convention over configuration </li></ul></ul>
    • 8. Plug-in Architecture <ul><li>Similar to Firefox and Eclipse </li></ul><ul><li>Add features by dropping in a jar </li></ul><ul><li>Several bundled plug-ins </li></ul><ul><ul><li>Tiles </li></ul></ul><ul><ul><li>JFreeChart </li></ul></ul><ul><ul><li>JasperReports </li></ul></ul><ul><ul><li>REST-Style URI mappings </li></ul></ul><ul><li>Plug-in registry growing steadily </li></ul>
    • 9. The Core Components <ul><li>Actions </li></ul><ul><li>Interceptors </li></ul><ul><li>Results </li></ul>
    • 10. Differences from Struts Classic <ul><li>No form beans </li></ul><ul><li>Actions are no longer singletons </li></ul><ul><li>HTTP-free </li></ul><ul><li>Intelligent defaults </li></ul><ul><li>Easy to extend with </li></ul><ul><ul><li>Interceptors </li></ul></ul><ul><ul><li>Results </li></ul></ul><ul><ul><li>Plug-ins </li></ul></ul>
    • 11. Action/Interceptor/Result The Request Pipeline
    • 12. ActionContext (ThreadLocal)
    • 13. MVC 2 <ul><li>Where C=Cool! </li></ul><ul><li>Request </li></ul><ul><ul><li>FilterDispatcher </li></ul></ul><ul><ul><ul><li>Dispatcher </li></ul></ul></ul><ul><ul><ul><ul><li>StrutsActionProxy </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>ActionInvocation [ThreadLocal] </li></ul></ul></ul></ul></ul>
    • 14. Action <ul><li>Packaged according to like kind </li></ul><ul><ul><li>Sort of like Java packages </li></ul></ul><ul><li>ThreadLocal (safe) </li></ul><ul><li>Typically extend ActionSupport </li></ul><ul><li>Contain your domain model </li></ul><ul><ul><li>Can be model driven </li></ul></ul><ul><li>May contain multiple methods </li></ul><ul><li>Not tangled up with Servlet/API </li></ul><ul><li>Easy to test! </li></ul>
    • 15. Action Mapping <ul><li>&lt;package name=&amp;quot;hr&amp;quot; namespace=&amp;quot;/hr&amp;quot; extends=&amp;quot;starter&amp;quot;&gt; </li></ul><ul><ul><li>&lt;action </li></ul></ul><ul><ul><li>name=“ uri “ class=“ class “ method=“ method &amp;quot;&gt; </li></ul></ul><ul><ul><li> &lt;result&gt;destination&lt;/result&gt; </li></ul></ul><ul><ul><li>&lt;/action&gt; </li></ul></ul><ul><li>&lt;package&gt; </li></ul>
    • 16. Wildcard Action Mapping <ul><li>&lt;package name=&amp;quot;hr&amp;quot; namespace=&amp;quot;/hr&amp;quot; extends=&amp;quot;starter&amp;quot;&gt; </li></ul><ul><ul><li>&lt;action </li></ul></ul><ul><ul><li>name=“employeeAction_*&amp;quot; </li></ul></ul><ul><ul><li>class=“HREmployeeManager&amp;quot; </li></ul></ul><ul><ul><li>method=“{1} &amp;quot;&gt; </li></ul></ul><ul><ul><li>&lt;result&gt;/employee/{1}.jsp&lt;/result&gt; </li></ul></ul><ul><ul><li>&lt;/action&gt; </li></ul></ul><ul><li>&lt;package&gt; </li></ul>
    • 17. HREmployeeManager Action <ul><li>class HREmployeeManager { </li></ul><ul><ul><li>private Employee model; </li></ul></ul><ul><ul><li>private EmployeeService service; </li></ul></ul><ul><ul><li>public List getList(){…} </li></ul></ul><ul><li>} </li></ul>
    • 18. Interceptor <ul><li>Intercepts request </li></ul><ul><ul><li>Think AOP </li></ul></ul><ul><li>Called before/after your action </li></ul><ul><li>Useful for cross-cutting concerns </li></ul><ul><li>Built-ins cover 98+% of all use cases </li></ul><ul><li>Configured at package or action level </li></ul><ul><li>Is central to the framework itself </li></ul><ul><ul><li>Eat your own dog food! </li></ul></ul>
    • 19. Interceptor Stack <ul><li>An interceptor has a specific role </li></ul><ul><ul><li>Parameter interception </li></ul></ul><ul><ul><li>Validation </li></ul></ul><ul><ul><li>Workflow </li></ul></ul><ul><li>Named “stacks” provide pluggable lists pre-assembled for goal specific cases </li></ul><ul><ul><li>defaultStack </li></ul></ul><ul><ul><li>fileUploadStack </li></ul></ul><ul><ul><li>modelDrivenStack </li></ul></ul><ul><ul><li>paramsPrepareParamsStack </li></ul></ul>
    • 20. Interceptor Configuration <ul><li>Easy to configure wrong! </li></ul><ul><li>config-browser plug-in provides a glimpse into the runtime </li></ul><ul><ul><li>More about this later </li></ul></ul>
    • 21. Timer Interceptor <ul><li>Stopwatch feature for action execution </li></ul><ul><ul><li>“ starts” before your action </li></ul></ul><ul><ul><li>“ stops” afterward </li></ul></ul><ul><li>Writes performance timings to log </li></ul><ul><li>Order of interceptors is interesting </li></ul><ul><ul><li>See next slide </li></ul></ul>
    • 22. Timer Interceptor (cont.) <ul><li>&lt;interceptors&gt; </li></ul><ul><li>&lt;interceptor-stack name=&amp;quot;stackWithTimer&amp;quot;&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot; timer &amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;defaultStack&amp;quot;/&gt; </li></ul><ul><li>&lt;/interceptor-stack&gt; </li></ul><ul><li>&lt;/interceptors&gt; </li></ul><ul><li>records action&apos;s execution with interceptors </li></ul>
    • 23. Timer Interceptor (cont.) <ul><li>&lt;interceptors&gt; </li></ul><ul><li>&lt;interceptor-stack name=&amp;quot;stackWithTimer&amp;quot;&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;defaultStack&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot; timer &amp;quot;/&gt; </li></ul><ul><li>&lt;/interceptor-stack&gt; </li></ul><ul><li>&lt;/interceptors&gt; </li></ul><ul><li>records only the action&apos;s execution time </li></ul>
    • 24. Default Stack <ul><li>&lt;interceptor-stack name=&amp;quot;defaultStack&amp;quot;&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;exception&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;alias&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;servletConfig&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;prepare&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;i18n&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;chain&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;debugging&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;profiling&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;scopedModelDriven&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;modelDriven&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;fileUpload&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;checkbox&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;staticParams&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;params&amp;quot;&gt; </li></ul><ul><li>&lt;param name=&amp;quot;excludeParams&amp;quot;&gt;dojo..*&lt;/param&gt; </li></ul><ul><li>&lt;/interceptor-ref&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;conversionError&amp;quot;/&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;validation&amp;quot;&gt; </li></ul><ul><li>&lt;param name=&amp;quot;excludeMethods&amp;quot;&gt;input,back,cancel,browse&lt;/param&gt; </li></ul><ul><li>&lt;/interceptor-ref&gt; </li></ul><ul><li>&lt;interceptor-ref name=&amp;quot;workflow&amp;quot;&gt; </li></ul><ul><li>&lt;param name=&amp;quot;excludeMethods&amp;quot;&gt;input,back,cancel,browse&lt;/param&gt; </li></ul><ul><li>&lt;/interceptor-ref&gt; </li></ul><ul><li>&lt;/interceptor-stack&gt; </li></ul>
    • 25. Result <ul><li>What should be returned to requester? </li></ul><ul><li>Many provided out of the box </li></ul><ul><li>It’s easy to write your own </li></ul><ul><ul><li>Graphics </li></ul></ul><ul><ul><li>JSON </li></ul></ul><ul><ul><li>PDF </li></ul></ul><ul><li>It’s another configurable object </li></ul>
    • 26. Result Types <ul><li>&lt;result-types&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;chain&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot; dispatcher &amp;quot; class=“…&amp;quot; default=&amp;quot;true&amp;quot; /&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;freemarker&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;httpheader&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;redirect&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;redirectAction&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;stream&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;velocity&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;xslt&amp;quot; class=“…&amp;quot;/&gt; </li></ul><ul><li>&lt;result-type name=&amp;quot;plainText&amp;quot; class=“…&amp;quot; /&gt; </li></ul><ul><li> &lt;result-type name=&amp;quot;plaintext&amp;quot; class=“…&amp;quot; /&gt; </li></ul><ul><li>&lt;/result-types&gt; </li></ul>
    • 27. Result Example <ul><li>&lt;action …&gt; </li></ul><ul><li>&lt;result name =&amp;quot;success&amp;quot; type =&amp;quot;dispatcher&amp;quot;&gt; </li></ul><ul><li>/employee/list.jsp </li></ul><ul><li>&lt;/result&gt; </li></ul><ul><li>&lt;/action&gt; </li></ul><ul><li>name and type are optional </li></ul><ul><ul><li>name defaults to success </li></ul></ul><ul><ul><li>type default can be set by package </li></ul></ul>
    • 28. Connecting the Wildcard Dots <ul><li>&lt;action name=“employeeAction_*“ class=“HREmployeeManager“ method=“{1} &amp;quot;&gt; </li></ul><ul><ul><li>&lt;result&gt;/employee/{1}.jsp&lt;/result&gt; </li></ul></ul><ul><li>&lt;/action&gt; </li></ul><ul><li>www.foo.com/employeeAction_list </li></ul><ul><ul><li>list() </li></ul></ul><ul><ul><li>list.jsp </li></ul></ul>
    • 29. Configuration Declaring the Web Site Capabilities
    • 30. struts.xml <ul><li>Core configuration file for framework </li></ul><ul><li>Can contain multiple packages </li></ul><ul><li>&lt;struts&gt; </li></ul><ul><ul><li>&lt;package name=“base&amp;quot; extends=&amp;quot;struts-default&amp;quot;&gt; </li></ul></ul><ul><ul><li>&lt;action...&gt; </li></ul></ul><ul><ul><li>&lt;/package&gt; </li></ul></ul><ul><ul><li>&lt;include file=“hr.xml&amp;quot;/&gt; </li></ul></ul><ul><ul><li>&lt;include file=“logon.xml&amp;quot;/&gt; </li></ul></ul><ul><ul><li>&lt;include file=“preferences.xml&amp;quot;/&gt; </li></ul></ul><ul><li>&lt;/struts&gt; </li></ul>
    • 31. struts-default.xml <ul><li>Most of your packages will extend this </li></ul><ul><ul><li>Directly/Indirectly </li></ul></ul><ul><li>Contains about everything you need </li></ul><ul><li>Packages form inheritance hierarchies </li></ul><ul><li>The key sections are </li></ul><ul><ul><li>package </li></ul></ul><ul><ul><li>result-types </li></ul></ul><ul><ul><li>interceptors/stacks </li></ul></ul>
    • 32. Package Inheritance <ul><li>&lt;package name=“hr&amp;quot; extends=“base“ namespace=&amp;quot;/hr&amp;quot;&gt; </li></ul><ul><ul><li>&lt;action name=“…”/&gt; </li></ul></ul><ul><li>&lt;/package&gt; </li></ul><ul><li>struts-default </li></ul><ul><ul><li>base </li></ul></ul><ul><ul><ul><li>hr </li></ul></ul></ul>
    • 33. Intelligent Configuration <ul><li>Declarative architecture </li></ul><ul><li>Configurable defaults </li></ul><ul><li>Extendable </li></ul><ul><ul><li>Framework extension points </li></ul></ul><ul><ul><li>Sub-packages </li></ul></ul><ul><li>Shipped in the struts2-core-2.m.n.jar </li></ul><ul><ul><li>struts-default.xml </li></ul></ul>
    • 34. Sample Declaration <ul><li>&lt;package name=“hr“ extends=“base“ namespace=&amp;quot;/hr&amp;quot;&gt; </li></ul><ul><li>&lt;action name=&amp;quot;list“ </li></ul><ul><li>method=“preload” class=“HREmployeeManager”&gt; </li></ul><ul><ul><li>&lt;result&gt;/pages/hr/employee/list.jsp&lt;/result&gt; </li></ul></ul><ul><li>&lt;/action&gt; </li></ul><ul><li>&lt;/package&gt; </li></ul>
    • 35. Constant Configuration <ul><li>Modify framework and plug-in behavior </li></ul><ul><li>Can be declared at multiple levels </li></ul><ul><li>Searched in the following order </li></ul><ul><ul><li>struts-default.xml </li></ul></ul><ul><ul><li>struts-plugin.xml </li></ul></ul><ul><ul><li>struts.xml </li></ul></ul><ul><ul><li>struts.properties </li></ul></ul><ul><ul><li>web.xml </li></ul></ul><ul><li>Subsequent files override previous ones </li></ul>
    • 36. struts.properties <ul><li>struts.devMode=true </li></ul><ul><li>struts.objectFactory=spring </li></ul><ul><li>struts.configuration.xml.reload=true </li></ul><ul><li>struts.freemarker.templatesCache=true </li></ul><ul><li>struts.ui.theme=simple </li></ul><ul><li>struts.enable.DynamicMethodInvocation=false </li></ul><ul><li>struts.custom.i18n.resources=resources.Messages </li></ul><ul><li>… </li></ul>
    • 37. OGNL/ValueStack Dynamic Data/Object Graph
    • 38. Dynamic Data <ul><li>Where is dynamic data stored? </li></ul><ul><ul><li>Data to generate pages </li></ul></ul><ul><ul><li>User input from pages </li></ul></ul><ul><li>Form beans are gone </li></ul><ul><li>Dependence on Servlet/API is bad </li></ul><ul><li>Welcome to the ValueStack </li></ul>
    • 39. ValueStack <ul><li>Leverages the OGNL framework </li></ul><ul><ul><li>Object Graph Navigation Language </li></ul></ul><ul><li>Extends OGNL to support searching stack </li></ul><ul><ul><li>Top down to locate object/property </li></ul></ul><ul><li>Where Interceptors put/get object data </li></ul><ul><li>Thread Safe </li></ul><ul><li>ActionContext . getContext ().getValueStack() </li></ul>
    • 40. Struts 2 and OGNL OGNL OGNL Context ( ActionContext ) Value Stack (OGNL root) |___Action |___other objects… #parameters #request #session #application #attr (searches p, r, s, then a)
    • 41. ValueStack <ul><li>Request “Object Stack” </li></ul><ul><li>OGNL expressions search it top down </li></ul><ul><li>Can specify object level </li></ul><ul><li>Common operations </li></ul><ul><ul><li>peek </li></ul></ul><ul><ul><li>pop </li></ul></ul><ul><ul><li>push </li></ul></ul>
    • 42. Type Conversions <ul><li>OGNL uses reflection to convert types </li></ul><ul><li>JavaBeans convention provides “hint” </li></ul><ul><li>Custom converters can be added </li></ul><ul><ul><li>Scope </li></ul></ul><ul><ul><ul><li>Bean/Model </li></ul></ul></ul><ul><ul><ul><li>Action </li></ul></ul></ul><ul><ul><ul><li>Application </li></ul></ul></ul>
    • 43. Tag Libraries The UI
    • 44. Struts 2 Tags <ul><li>Tags are divided into 2 sets </li></ul><ul><ul><li>UI </li></ul></ul><ul><ul><ul><li>Form/Non-Form </li></ul></ul></ul><ul><ul><ul><li>Ajax </li></ul></ul></ul><ul><ul><ul><ul><li>Leverages dojo </li></ul></ul></ul></ul><ul><ul><li>Generic </li></ul></ul><ul><ul><ul><li>Control </li></ul></ul></ul><ul><ul><ul><ul><li>if, else, iterator </li></ul></ul></ul></ul><ul><ul><ul><li>Data </li></ul></ul></ul><ul><ul><ul><ul><li>bean, text, url </li></ul></ul></ul></ul>
    • 45. Struts 2 Tags <ul><li>Decoupled from underlying view technology </li></ul><ul><ul><li>JSP </li></ul></ul><ul><ul><li>Velocity </li></ul></ul><ul><ul><li>FreeMarker </li></ul></ul><ul><li>Markup via Freemarker templates </li></ul>
    • 46. S2 Tag Syntax <ul><li>The value attribute is not a string </li></ul><ul><ul><li>It’s an OBJECT </li></ul></ul><ul><li>What you pass is evaluated as an expression! </li></ul><ul><li>&lt;s:sometag … value=“foo”/&gt; </li></ul><ul><ul><li>Looks for getFoo() </li></ul></ul><ul><li>&lt;s:sometag … value=“{‘foo’}”/&gt; </li></ul><ul><ul><li>String literal is passed </li></ul></ul>
    • 47. Tag Templates <ul><li>The markup generated is your choice </li></ul><ul><ul><li>HTML </li></ul></ul><ul><ul><li>XML </li></ul></ul><ul><ul><li>JSON </li></ul></ul><ul><ul><li>WML </li></ul></ul><ul><ul><li>… </li></ul></ul>
    • 48. UI Tag Templates <ul><li>Template technology is FreeMarker </li></ul><ul><li>CSS classes can be used to control L&amp;F </li></ul><ul><li>You may tweak provided templates </li></ul><ul><li>Tight affinity with ValueStack </li></ul>
    • 49. Base select Component <ul><li>View technology agnostic </li></ul><ul><li>org.apache.struts2.components.Select </li></ul><ul><li>Generates markup via TemplateEngine </li></ul><ul><li>S2 provides FreeMarkerTemplateEngine </li></ul><ul><ul><li>Unites ValueStack &amp; FreeMarker </li></ul></ul>
    • 50. &lt;s:select/&gt; JSP Custom Tag <ul><li>org.apache.struts2.views.jsp.ui.SelectTag </li></ul><ul><li>Renders a select widget </li></ul>
    • 51. &lt;@s.select/&gt; FreeMarker Tag <ul><li>org.apache.struts2.views.freemarker.tags.SelectModel </li></ul><ul><li>Renders a select widget </li></ul>
    • 52. StrutsRequestWrapper <ul><li>JSTL does not know OGNL </li></ul><ul><li>This class wraps the Struts request </li></ul><ul><li>Delegates to the Value Stack </li></ul><ul><li>${customer.address.city} </li></ul><ul><ul><li>Resolves to stack.find under the covers </li></ul></ul>
    • 53. S2 and JSTL <ul><li>OGNL values are exposed to JSP/JSTL </li></ul><ul><li>Expression syntax is a little different </li></ul><ul><ul><li>JSTL: ${a.b.c} </li></ul></ul><ul><ul><li>OGNL: %{a.b.c} </li></ul></ul><ul><li>Beware of JSP 2.1 Unified EL JSR 245 </li></ul><ul><ul><li>EL has been expanded to interpret #{} </li></ul></ul><ul><ul><li>Clashes with OGNL usage for Maps </li></ul></ul><ul><ul><ul><li>#{ &amp;quot;foo&amp;quot; : &amp;quot;foo value&amp;quot;, &amp;quot;bar&amp;quot; : &amp;quot;bar value&amp;quot; } </li></ul></ul></ul>
    • 54. Themes <ul><li>S2 UI tags grouped into themes </li></ul><ul><ul><li>simple - minimal with no &amp;quot;bells and whistles&amp;quot; </li></ul></ul><ul><ul><li>xhtml - uses common HTML practices </li></ul></ul><ul><ul><li>css_xhtml - xhtml theme re-implemented using strictly CSS for layout </li></ul></ul><ul><ul><li>Ajax - based on the xhtml theme that provides advanced AJAX features </li></ul></ul><ul><li>Specified globally or at the tag level </li></ul>
    • 55. Simple Theme &lt;H2&gt;Employee Save&lt;/H2&gt; &lt;s:form&gt; &lt;s:textfield key=&amp;quot;employee.name“ required=&amp;quot;true&amp;quot;/&gt; &lt;s:textfield key=&amp;quot;employee.department“ required=&amp;quot;true&amp;quot;/&gt; &lt;/s:form&gt;
    • 56. XHTML Theme &lt;H2&gt;Employee Save&lt;/H2&gt; &lt;s:form&gt; &lt;s:textfield key=&amp;quot;employee.name“ required=&amp;quot;true&amp;quot;/&gt; &lt;s:textfield key=&amp;quot;employee.department“ required=&amp;quot;true&amp;quot;/&gt; &lt;/s:form&gt;
    • 57. Business Validation Rules and Regulations
    • 58. Validation Styles <ul><li>Annotations </li></ul><ul><li>XML </li></ul><ul><li>Java </li></ul>
    • 59. Simple Field Example <ul><li>Form </li></ul><ul><ul><li>&lt;s:textfield key=&amp;quot;age&amp;quot;/&gt; </li></ul></ul><ul><li>Action </li></ul><ul><ul><li>private int age; get/set </li></ul></ul><ul><li>Validator &lt;ActionClassName&gt;-validation.xml </li></ul><ul><ul><li>&lt;field name=&amp;quot;age&amp;quot;&gt; </li></ul></ul><ul><ul><ul><li>&lt;field-validator type=&amp;quot;int&amp;quot;&gt; </li></ul></ul></ul><ul><ul><ul><ul><li>&lt;param name=&amp;quot;min&amp;quot;&gt;13&lt;/param&gt; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>&lt;param name=&amp;quot;max&amp;quot;&gt;19&lt;/param&gt; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>&lt;message&gt;Only people ages 13 to 19 allowed&lt;/message&gt; </li></ul></ul></ul></ul><ul><ul><ul><li>&lt;/field-validator&gt; </li></ul></ul></ul><ul><ul><li>&lt;/field&gt; </li></ul></ul>
    • 60. Validator Types <ul><li>conversion </li></ul><ul><li>date </li></ul><ul><li>email </li></ul><ul><li>short – int – long - double </li></ul><ul><li>regex &lt;takes a regular expression&gt; </li></ul><ul><li>required </li></ul><ul><li>requiredstring </li></ul><ul><li>stringlength </li></ul><ul><li>url </li></ul><ul><li>visitor - conditionalvisitor </li></ul><ul><li>fieldexpression &lt;resolves an OGNL expression&gt; </li></ul><ul><li>expression &lt;resolves an OGNL expression&gt; </li></ul>
    • 61. Another Field Example <ul><li>&lt;field name=“password&amp;quot;&gt; </li></ul><ul><li>&lt;field-validator type=&amp;quot;expression&amp;quot;&gt; </li></ul><ul><li>&lt;param name=&amp;quot;expression&amp;quot;&gt; </li></ul><ul><li>password.equals(password2) </li></ul><ul><li>&lt;/param&gt; </li></ul><ul><li>&lt;message&gt; </li></ul><ul><li>Password 2 must equal ${password} </li></ul><ul><li>&lt;/message&gt; </li></ul><ul><li>&lt;/field-validator&gt; </li></ul><ul><li>&lt;/field&gt; </li></ul>
    • 62. Non-Field Validation <ul><li>&lt;validators&gt; </li></ul><ul><ul><li>&lt;validator type=&amp;quot;expression&amp;quot;&gt; </li></ul></ul><ul><ul><li>&lt;param name=&amp;quot;expression“&gt; ( (a==b) &amp;&amp; (b==c) )&lt;/param&gt; </li></ul></ul><ul><ul><li>&lt;message&gt;all three fields must be the same&gt;&lt;/message&gt; </li></ul></ul><ul><ul><li>&lt;/validator&gt; </li></ul></ul><ul><li>&lt;/validators&gt; </li></ul>
    • 63. Plug-ins Extensions Simplified
    • 64. Benefits of plug-ins <ul><li>Strategic points in the framework where you can </li></ul><ul><ul><li>Provide you own implementations </li></ul></ul><ul><ul><li>Add new features </li></ul></ul><ul><li>Add functionality without modifying code </li></ul><ul><ul><li>Open-Closed Principle </li></ul></ul>
    • 65. Configuration Browser <ul><li>Exposes the runtime configuration </li></ul><ul><li>Accessed via a browser </li></ul><ul><ul><li>http://.../config-browser/index.action </li></ul></ul>
    • 66. OGNL Viewer <ul><li>Provides debugging screens to provide insight into the data behind the page </li></ul><ul><li>Accessed via a browser </li></ul><ul><ul><li>http://..?debug={flag} </li></ul></ul><ul><li>Flag values </li></ul><ul><ul><li>xml, console, command, browser </li></ul></ul><ul><li>Make sure </li></ul><ul><ul><li>DebuggingInterceptor is included </li></ul></ul><ul><ul><li>struts.devMode=true </li></ul></ul>
    • 67. Wrap up Odds &amp; Ends
    • 68. My Web Site <ul><li>www.struts2inaction.com </li></ul><ul><li>The cobbler’s children have no shoes </li></ul><ul><li>Too many paying gigs to lace up my own site! </li></ul><ul><li>Vacation time coming </li></ul><ul><ul><li>It will rock! </li></ul></ul>
    • 69. Resources <ul><li>Manning </li></ul><ul><li>Nabble </li></ul><ul><li>Google </li></ul><ul><li>Also watch for </li></ul><ul><ul><li>Struts 2 in Practice (Wes Wannemacher) </li></ul></ul>

    ×