Component Framework Primer for JSF Users
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Component Framework Primer for JSF Users

on

  • 5,819 views

JSF Summit 2009 presentation covering three component-centric web frameworks: JSF, Wicket and Tapestry.

JSF Summit 2009 presentation covering three component-centric web frameworks: JSF, Wicket and Tapestry.

Statistics

Views

Total Views
5,819
Views on SlideShare
5,797
Embed Views
22

Actions

Likes
2
Downloads
165
Comments
1

2 Embeds 22

http://www.slideshare.net 21
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • good
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Component Framework Primer for JSF Users Presentation Transcript

  • 1. Component Framework Primer for JSF Users Andy Schwartz | Oracle Corporation
  • 2. What?
    • What are we doing?
      • Comparing server-side component-centric frameworks
      • Understanding approaches to common problems
    • What is a server-side component-centric framework?
      • User interface component model defined on server
      • Components hold properties, children, fire events
      • Swing-like approach for web content
    • What frameworks?
      • JSF, Wicket and Tapestry
    • What else is there?
      • Client-side (jQuery, Dojo)
      • Hybrid (GWT)
      • MVC (Struts, RoR)
  • 3. Why?
    • JSF has historically been a target of criticism
    • Often compared to related frameworks
    • Important to understand JSF’s limitations
    • JSF 2 addresses many of these issues
    • Still room for improvement
    • We can learn from other frameworks
    • We can continue to evolve/improve JSF
  • 4. Why Wicket and Tapestry?
    • Similar in scope to JSF
    • Popular choices
    • Many areas of overlap
    • Different approaches
    • Interesting comparisons
    • Plenty of lessons to learn
  • 5. Who?
    • User Interface Technology Architect, Oracle
    • Developing user interface frameworks since 1993
    • JSR-314/JSF 2.0 Expert Group Representative
    • Wicket/Tapestry Student
    • Biased, but honest :-)
  • 6. Agenda
    • Hello, Frameworks!
    • Event Handling
    • Ajax
    • Navigation
    • Input Processing
    • Custom components
    • Wrap up
  • 7.
    • Hello, JSF!
  • 8. JSF History
    • Originally standardized under JSR-127, 2004.
    • Standard piece of Java EE platform (Web Profile)
    • Sun serves as spec lead (Ed Burns, Roger Kitain)
    • JSR-252/JSF 1.2 enhancements, 2006
    • JSR-314/JSF 2.0 major release, 2009
    • Two widely used implementations
      • Mojarra (Reference Implementation)
      • MyFaces
  • 9. JSF Vision
    • Swing-like component/event model
    • Declarative component tree specification
    • Integration with existing standards
    • Split logical (components) and physical (markup)
    • Tooling
    • Extensibility
  • 10. What is a Page?
    • Legacy: Each page defined by a JSP (JSPX)
    • Now: Facelets standardized, preferred over JSP
    • Combines XHTML and component tags
    • Component tree definition specified via tags
    • Other view declaration languages (VDLs) available
      • JSF Templating, Gracelets
  • 11.
    • Saying Hello
    • (JSF)
  • 12. Grunge: web.xml <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class> javax.faces.webapp.FacesServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping>
  • 13. My First JSF Page <html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:h=&quot;http://java.sun.com/jsf/html&quot;> <head><title>My First JSF Page</title></head> <body> <!-- Our first JSF component usage --> Hello, <h:outputText value=&quot;World&quot;/>! </body> </html>
  • 14. JSF Rendering
    • Page definition drives component tree creation
    • Component tree contains UIComponent instances
    • UIComponents delegate to Renderers
    • Response produced by traversing component tree
    • UIComponents/Renderers generate markup
    • Markup written via ResponseWriter
  • 15. What Happens After Rendering?
    • Component tree state saved via StateManager
    • State stored in session or client
    • Component tree restored on postback
    • JSF 2.0 optimization: partial state saving
  • 16. Bindings
    • Component attributes can be bound
    • Allows components to access dynamic data
    • Specified via Unified Expression Language (EL)
    • Bindings used for both reading and writing
  • 17. A Simple Binding <h:outputText value=&quot;#{sessionScope.user.firstName}&quot;/>
  • 18. Implicit Objects
    • Bindings have access implicit objects/scopes
    • Servlet-related scopes:
      • applicationScope
      • sessionScope
      • requestScope
    • JSF-specific scopes
      • viewScope
      • flash
      • component
    • Many more objects exposed
  • 19. Managed Beans
    • POJOs
    • Named
    • Scoped
    • Container-managed
  • 20. Managed Bean Registration <faces-config> <managed-bean> <managed-bean-name>user</managed-bean-name> <managed-bean-class>demo.User</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
  • 21. Managed Bean Registration @ManagedBean @SessionScoped public class User { public String getFirstName() { … } }
  • 22. Managed Bean Reference <!-- Instead of this: --> <h:outputText value=&quot;#{sessionScope.user.firstName}&quot;/> <!-- We can now do this: --> <h:outputText value=&quot;#{user.firstName}&quot;/>
  • 23.
    • Hello, Wicket!
  • 24. Wicket Quick History
    • Founded by Johnathan Locke, 2005
    • Originally hosted at SourceForge
    • Moved to Apache, 2007
    • Graduated to top level project, June 2007
    • Current version: 1.4.3 (as of November 2009)
  • 25. Wicket Vision
    • Complete separation of markup and logic
    • Web designers do HTML
    • Application developers do Java
    • Designers benefit from previewability
    • Developers benefit from type-safety
    • No special tooling required
  • 26. What is a Page?
    • Markup lives in a .html file
    • Code/components live in a .java file
    • Properties/messages in a .properties file
    • All files live on the class path
    • All files for a page share a name
    • Components correlated across html/java by id
  • 27.
    • Saying Hello
    • (Wicket)
  • 28. Grunge: web.xml <filter> <filter-name>wicket</filter-name> <filter-class> org.apache.wicket.protocol.http.WicketFilter </filter-class> <filter-mapping> <filter-name>wicket</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </filter>
  • 29. Grunge: web.xml <init-param> <param-name> applicationClassName </param-name> <param-value> org.demo.wicket.HelloApplication </param-value> </init-param>
  • 30. My First Wicket Application public class HelloApplication extends WebApplication { @Override public Class<Hello> getHomePage() { return Hello.class; } }
  • 31. My First Wicket Page (HTML) <html xmlns:wicket=&quot;…&quot;> <head><title>Hello, Wicket!</title></head> <body> <!-- My first Wicket component (html) --> Hello, <span wicket:id=&quot;name&quot; >Foo</span>! </body> </html>
  • 32. My First Wicket Page (Java) public class Hello extends WebPage { public Hello() { // My first Wicket component (Java) add(new Label( &quot;name&quot; , &quot;World&quot;)); } }
  • 33. Wicket Rendering
    • Markup exposed via MarkupStream
      • MarkupElements: RawText, ComponentTag
    • ComponentTags correlated with Components
    • onRender() called for each component
    • onComponentTag(): modify/render start tag
    • onComponentBodyTag(): modify/render body
    • MarkupElements written to response.
  • 34. What Happens After Rendering?
    • Page state stored in page store
    • Pluggable page store behavior
      • DiskPageStore leverages file system for old pages
    • Page restored on postback
  • 35. What is a Wicket Model?
    • Wicket models bind domain layer objects to components.
    • (Similar to EL ValueExpressions in JSF)
  • 36. IModel Contract T getObject() void setObject(T object)
  • 37. Components and Models
    • IModel<?> getDefaultModel()
    • Most components read from model.
    • Some components write to model.
  • 38. Simple Model
    • Model class implements IModel
    • Stores model object locally
    • We have been using it already
  • 39. Simple Model Sample // This: add(new Label(&quot;name&quot;, &quot;World&quot;); // Is shorthand for: add(new Label(&quot;name&quot;, new Model(&quot;World&quot;)));
  • 40. Static Model
    • Simple Models are static.
    // This is static: add(new Label(&quot;random&quot;, new Model<Double>(Math.random()) ));
  • 41. Dynamic Model
    • Override getObject() for dynamic.
    // This is dynamic: add(new Label(&quot;reallyRandom&quot;, new Model<Double>() { public Double getObject() { return Math.random(); } }));
  • 42. Some More Models
    • PropertyModel
    • CompoundPropertyModel
    • LoadableDetachableModel
    • ResourceModel
  • 43.
    • Hello, Tapestry!
  • 44. Tapestry Quick History
    • Founded by Howard Lewis Ship, 2000
    • Hosted at Apache
    • Graduated to top level project, June 2006
    • Current release: 5.1 (as of November 2009)
  • 45. Tapestry Vision
    • Similar separation of markup/logic
    • Convention over Configuration
    • Inversion of Control
    • POJOs/annotations
    • Performance
  • 46. What is a Page?
    • Markup lives in a .tml file
    • Code/components live in a .java file
    • Properties/messages in a .properties file
    • TML files live in web root
    • Other files on the class path
    • All files for a page share a name
  • 47.
    • Saying Hello
    • (Tapestry)
  • 48. Grunge: web.xml <filter> <filter-name>tapestry</filter-name> <filter-class> org.apache.tapestry5.TapestryFilter </filter-class> </filter> <filter-mapping> <filter-name>tapestry</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
  • 49. Grunge: web.xml <context-param> <param-name> tapestry.app-package </param-name> <param-value> org.example.tapestry </param-value> </context-param>
  • 50. My First Tapestry Page (TML) <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- My first Tapestry component. --> <!-- Note: We don't really need a component. --> Hello, <t:textoutput t:value=&quot;name&quot;/>! </body> </html>
  • 51. My First Tapestry Page (Java) public class Index { @Property private String name; }
  • 52. Tapestry Rendering
    • State machine/queue-based rendering
      • No recursive component tree traversal
    • Components hook into rendering phases
      • SetupRender, BeginRender, BeforeRenderBody, etc.
    • Specified via annotations or naming conventions
    • Hooks write response to MarkupWriter
      • Streaming API with access to DOM-like structure
  • 53. What Happens After Rendering?
    • Persistent properties are state saved
      • @Persist annotation identifes properties to persist
    • Page is cleaned up and returned to pool
    • On postback, page instance retrieved from pool
    • Persistent property values are restored
    • Pooling is for performance (smaller footprint)
    • Implies mostly static page structures
  • 54.
    • Take 2: t:id
  • 55. Take 2: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> <!-- Does this seem familiar? --> Hello, <span t:id=&quot;nameOutput&quot; >Foo</span>! </body> </html>
  • 56. Take 2: Java public class Index { @Property private String name; @Component( parameters={&quot;value=name&quot;}) private TextOutput nameOutput; }
  • 57.
    • Take 3: t:type
  • 58. Take 3: TML <html xmlns:t=&quot;…&quot;> <head><title>Hello, Tapestry!</title></head> <body> Hello, <span t:type=&quot;textoutput&quot; t:value=&quot;name&quot;>Foo</span>! </body> </html>
  • 59. Facelets Flashback <!-- Remember this? --> <span jsfc=&quot;h:outputText&quot; value=&quot;#{name}&quot;>Foo</span>!
  • 60. Tapestry Property Expressions
    • String notations for specifying object paths
    • Similar to EL
    • Supports referencing properties and methods
    • Used for parameters and template expansions
    • Compiled to Java classes (no reflection)
  • 61. Property Expressions <!-- Component parameter --> <div><t:textoutput t:value=&quot;user.name&quot;/></div> <!-- Template expansion --> <div>${user.name}</div>
  • 62. Binding Expressions
    • Parameters can bind to other types of values
    • Prefix identifies binding type:
      • prop
      • literal
      • asset
      • context
      • component
      • message
  • 63. Binding Expressions <!-- Property Binding--> Hello, <t:textoutput t:value=&quot;name&quot;/>! <!-- Literal Binding--> Hello, <t:textoutput t:value=&quot;literal:World&quot;/>!
  • 64. Some Initial Thoughts
    • Key difference: declarative vs programmatic component tree specification
    • JSF favors declarative approach
    • Wicket requires programmatic approach
    • Tapestry is somewhere in the middle
    • Component abstraction vs. direct access to HTML
  • 65. Some More Thoughts
    • Implicit per-page Java object is convenient
    • Possible to simulate with JSF (viewScope bean)
    • Consider formalizing this in JSF?
  • 66.
    • Event Handling
  • 67. JSF Event Handling
    • Inspired by Swing Event Model
    • Listeners registered on components
    • Components fire events
    • Declarative: listeners referenced via EL
  • 68. JSF Event Handling <h:form> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.increment}&quot;/> <h:outputText value=&quot;#{counter.count}&quot;/> </h:form>
  • 69. JSF Event Handling @ManagedBean @SessionScoped public class Counter { public int getCount() { return count; } public void increment() { count++; } private int count; }
  • 70. Wicket Event Handling
    • Components expose event-specific hooks
    • Subclasses override to receive notifications
  • 71. Wicket Event Handling <form wicket:id=&quot;form&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; wicket:id=&quot;button&quot;/> <span wicket:id=&quot;count&quot;>count</span> </form>
  • 72. Wicket Event Handling public class EventsPage extends WebPage { public EventsPage() { Button button = new Button(&quot;button&quot;) { @Override public void onSubmit() { count++; } }; } private int count; }
  • 73. Wicket Event Handling
    • onSubmit() exposed at both Button and Form level
    • Button onSubmit() called first
    • Link component provides form/POST-free events
    • onClick() vs. onSubmit()
  • 74. Tapestry Event Handling
    • Naming Conventions
    • Annotations
  • 75. Tapestry Event Handling <t:form t:id=&quot;form1&quot;> <input type=&quot;submit&quot; value=&quot;Increment&quot; t:type=&quot;submit&quot; t:id=&quot;button1&quot;/> ${count} </t:form>
  • 76. Tapestry Event Handling public class Events { @Persist @Property private int count; // Called when any form is submitted void onSubmit() { count++; } }
  • 77. Tapestry Event Handling // All of these work too! // Called when form 1 is submitted void onSubmitFromForm1() { count++ } // Called when any button is selected void onSelected() { count++; } // Called when button1 is selected void onSelectedFromButton1() { count++; }
  • 78. Tapestry Event Handling // And these too @OnEvent(value=&quot;selected&quot;, component=&quot;button1&quot;) void increment() { count++ } @OnEvent(value=&quot;submit&quot;, component=&quot;form&quot;) void foo() { count++ }
  • 79. Tapestry Event Handling
    • Component-specific events before form
    • Global events before component-specific
    • ActionLink provides form/POST-free events
  • 80. Event Handling Wrap Up
    • Three very different approaches
    • Managed bean annotations simplify JSF approach
    • Possible to add a Tapestry-like solution to JSF?
    • Possible to add Wicket-like solution to JSF?
      • Programmatic component creation cases, yes.
      • What about other cases?
    • Form-level submit hook is nice
  • 81.
    • Ajax
  • 82. JSF Ajax
    • Before: Take your pick
      • ADF/Ice/Rich/Prime/Trinidad
    • Now: Standard Ajax APIs/implementation
    • Ajax behaviors attached to components
    • Primarily declarative solution
    • Programmatic APIs available too
  • 83. JSF Ajax
    • <h:form>
    • <h:commandButton value=&quot;Increment&quot;
    • actionListener=&quot;#{counter.increment}&quot;>
    • <f:ajax render=&quot;count&quot;/>
    • </h:commandButton>
    • <h:outputText value=&quot;#{counter.count}&quot;
    • id=&quot;count&quot; />
    • </h:form>
  • 84. JSF Ajax <f:ajax render=&quot;count&quot;/> <h:commandButton value=&quot;Increment&quot; actionListener=&quot;#{counter.increment}&quot;> <h:commandButton value=&quot;Reset&quot; actionListener=&quot;#{counter.reset}&quot;> </f:ajax>
  • 85. JSF Ajax
    • All standard components support behaviors
    • Attach points are component-specific
      • Action, valueChange, focus, blur, mouse over, etc…
    • Behavior mechanism is extensible
    • Not specific to Ajax
  • 86. Wicket Ajax
    • Ajax Components
    • Behaviors
  • 87. Wicket Ajax AjaxButton button = new AjaxButton(&quot;button&quot;) { @Override public void onSubmit( AjaxRequestTarget target , Form form) { count++; if (target != null) { target.addComponent(label); } }});
  • 88. Wicket Ajax label = new Label(&quot;count&quot;, …); label. setOutputMarkupId(true);
  • 89. Wicket Ajax
    • Many convenience components, behaviors
    • Fallback behavior: AjaxFallbackLink
    • setOutputMarkupPlaceholderTag()
    • Ajax debug window
  • 90. Tapestry Ajax
    • Ajax Zones
    • Mixins
  • 91. Tapestry Ajax <t:form t:id=&quot;form1&quot; zone=&quot;countZone&quot; > <input type=&quot;submit&quot; value=&quot;Increment&quot; t:type=&quot;submit&quot; t:id=&quot;button1&quot;/> <t:zone t:id=&quot;countZone&quot;> Hello, ${count} </t:zone> </t:form>
  • 92. Tapestry Ajax public class Ajax { @InjectComponent private Zone countZone; Object onSubmitFromForm1() { return countZone.getBody(); } }
  • 93. Tapestry Ajax
    • Zone supported by Form, ActionLink, EventLink
    • MultiZoneUpdate
    • Mixins: autocomplete
  • 94. Ajax Wrap Up
    • JSF 2.0 Ajax is competitive with other solutions
    • Wicket Ajax debug window is nice
      • JSF implementations could provide equivalent
    • Improve JSF's fallback story?
    • Resolve (or document) rendered toggling behavior
  • 95.
    • Navigation
  • 96. JSF Navigation
    • Traditional: POST-based navigation
    • POST triggers action
    • Action determines outcome
    • Outcome mapped to target view
  • 97. JSF Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @RequestScoped public class Navigation { public String goToPageB() { return &quot;success&quot;; } }
  • 98. JSF Navigation <navigation-rule> <from-view-id>/pageA.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/pageB.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule>
  • 99. JSF Implicit Navigation
    • Declarative navigation is good for many cases
    • Perhaps too verbose for simple cases
    • Implicit navigation simplifies simple cases
    • Outcome implicitly treated as view id
    • Bypasses faces-config.xml
  • 100. JSF Implicit Navigation <h:commandButton action=&quot;#{nav.goToPageB}&quot;/> @ManagedBean(name=&quot;nav&quot;) @RequestScoped public class Navigation { public String goToPageB() { // No faces-config entry required return &quot;pageB&quot; ; } }
  • 101. JSF Pre-Emptive Navigation
    • Implict navigation simplifies, but still POST-only
    • Not GET/bookmark-friendly
    • Pre-emptive navigation: best of both worlds
    • Navigation rules aggressively evaluated
    • <h:link>/<h:button> produce GET requests
  • 102. JSF Pre-Emptive Navigation <!-- Use navigation rules to determine &quot;success&quot; outcome target --> <h:button outcome=&quot;success&quot;/> <!-- Both pre-emptive and implicit. No faces-config needed. --> <h:button outcome=&quot;pageB&quot;/>
  • 103. Wicket Navigation
    • Programmatic navigation: setResponsePage()
    • Class vs. instance
  • 104. Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { setResponsePage(PageB.class); } };
  • 105. Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { PageB pageB = new PageB(); // Configure PageB instance… setResponsePage(pageB); } }; Wicket Navigation
  • 106. Wicket Navigation
    • Direct navigation also supported
    • BookmarkablePageLink
    • wicket:link
  • 107. Wicket Navigation <!-- HTML --> <a wicket:id=&quot;bookmarkable&quot; href=&quot;PageB.html&quot;>Navigate To Page B</a> // Java form.add( new BookmarkablePageLink(&quot;bookmarkable&quot;, PageB.class));
  • 108. Wicket Navigation <!-- No Java code required. --> <wicket:link> <ul> <li><a href=&quot;PageA.html&quot;>Page A</a></li> <li><a href=&quot;PageB.html&quot;>Page B</a></li> <li><a href=&quot;PageC.html&quot;>Page C</a></li> <li><a href=&quot;PageD.html&quot;>Page D</a></li> </ul> </wicket:link>
  • 109. Tapestry Navigation
    • Programmatic navigation: onSubmit() return
    • Like Wicket, navigate to class or instance
    • Instance page injected
  • 110. Tapestry Navigation public class PageA { Object onSubmitFromForm1() { return PageB.class; } }
  • 111. Tapestry Navigation public class PageA { @InjectPage private PageB pageB; Object onSubmitFromForm1() { // Configure pageB instance... return pageB; } }
  • 112. Tapestry Navigation
    • Direct navigation also supported
    • t:pageLink
  • 113. Tapestry Navigation <t:pagelink t:page=&quot;PageB&quot;>Go</t:pagelink>
  • 114. Navigation Wrap Up
    • JSF 2.0 enhancements simplify navigation
    • String outcomes vs. class/instance
    • Introduce class/instance support in JSF?
    • Redirect defaults
  • 115.
    • Input Processing
  • 116. JSF Input Processing
    • EditableValueHolder lifecycle
      • Decode
      • Conversion
      • Validation
      • Update model
    • Value referenced via value expression
  • 117. JSF Input Processing <h:inputText value=&quot;#{user.name}&quot;/> @ManagedBean public class User { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
  • 118. JSF Conversion
    • Converters control transformation to/from string
    • Attached to EditableValueHolder components
    • Default conversion for most types
    • Date/time and number converters for more control
    • Custom converters
  • 119. JSF Conversion <h:inputText value=&quot;#{user.age}&quot;> <f:convertNumber integerOnly=&quot;true&quot;/> </h:inputText>
  • 120. JSF Validation
    • Validators verify converted value
    • Attached to EditableValueHolder components
    • Various standard validators provided with JSF
    • Also possible to implement custom validators
    • JSF 2.0 also applies JSR-303 validation constraints
  • 121. JSF Validation <h:inputText value=&quot;#{user.age}&quot;> <f:validateLongRange minimum=&quot;18&quot;/> </h:inputText>
  • 122. More JSF Validation
    • Feedback
      • Typically displayed via <h:messages>/<h:message>
      • More interesting feedback possible
    • Multi-component validation
      • Historically very tricky
      • PostValidate system event makes this much easier
    • Client-side validation
      • No out-of-box support
      • 3rd party solutions available (Trinidad/ADF Faces)
    • Ajax Validation
      • Facilitated by <f:ajax>
  • 123. Wicket Input Processing
    • Similar lifecycle to JSF
      • Required field validation
      • Conversion
      • Validation
      • Push to model
      • onSubmit/onError
    • Value referenced via Model contract
  • 124. Wicket Input Processing <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;firstName&quot;/> // Java User user = getUser(); form.add(new TextField(&quot;firstName&quot;, new PropertyModel(user, &quot;name&quot;)));
  • 125. Wicket Conversion
    • IConverter contract, similar to JSF Converter
    • Converts to/from string
    • Default converters
    • Type derived or hinted
    • Custom converters
      • Override getConverter()
  • 126. Wicket Validation
    • IValidator, similar to JSF Validator
    • Validators attached programmatically
  • 127. Wicket Validation <!-- HTML --> <input type=&quot;text&quot; wicket:id=&quot;age&quot;/> // Java add(new TextField(&quot;age&quot;, new PropertyModel(getUser(), &quot;age&quot;)) .add(NumberValidator.minimum(18)));
  • 128. More Wicket Validation
    • Feedback
      • FeedbackPanel (like h:messages)
      • FormComponentFeedbackBorder
    • Multi-component validation
      • IFormValidator
    • Client-side validation
      • No out-of-box support
      • Ajax validation preferred
    • Ajax Validation
      • AjaxFormValidatingBehavior
  • 129. Tapestry Input Processing
    • Similar lifecycle to JSF, Wicket
      • Conversion
      • Validation
      • Push to model
      • onSuccess/onFailure
    • Value referenced via property expressions
  • 130. Tapestry Input Processing <!-- TML --> <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.name&quot;/> // Java public class Input { @Property private User user; }
  • 131. Tapestry Conversion
    • FieldTranslator, similar to Converter/IConverter
    • Event-based conversion
      • toclient
      • parseclient
  • 132. Tapestry Conversion Events public class Input { String onToClientFromAge() { // Return String representation of age } Object onParseClientFromAge(String input) { // Return converted representation of age } }
  • 133. Tapestry Validation
    • FieldValidator, similar to Validator/Ivalidator
    • Constraints attached via component parameters
    • Event and annotation-based validation
  • 134. Parameter-Based Validation <input type=&quot;text&quot; t:type=&quot;textfield&quot; t:value=&quot;user.age&quot; t:validate=&quot;required,min=18&quot;/>
  • 135. Event-Based Validation void onValidateFromAge(Integer value) throws ValidationException { if (value < 18) throw new ValidationException(&quot;Too young!&quot;); }
  • 136. Anntation-Based Validation public class Input { @Property @Validate(&quot;required,min=18&quot;) private int age; }
  • 137. More Tapestry Validation
    • Feedback
      • Border highlight, hover text
      • <t:errors>
    • Multi-component validation
      • onValidateForm()
    • Client-side validation
      • Provided automatically for standard validators
    • Ajax Validation
      • Client-side validation preferred
  • 138. Input Processing Wrap Up
    • Similar input processing across frameworks
      • Surprise?
    • Pull client-side validation into JSF?
    • Improve feedback reporting
    • Encourage use of PostValidate system event for multi-component validation
  • 139.
    • Custom Components
  • 140. JSF: Old School (Java)
    • Java class (extends UIComponent)
    • Renderer class
    • Tag class
    • faces-config.xml
    • tld
  • 141. JSF: New School (Java)
    • Annotations replace faces-cofig.xml
    • Default Facelets handlers replace Tag class
    • taglib.xml replaces tld
  • 142. JSF: New School (Composite)
    • Single Facelets file defines composite component
    • Installed in resources directory
    • Component namespace/name derived
    • No external configuration
    • Optional Java component class
    • Optional properties file
  • 143. resources/demo/titleBorder.xhtml <html ... ><body> <composite:implementation> <div class=&quot;tb-root&quot;> <div class=&quot;tb-title&quot;> #{cc.attrs.title} </div> <div class=&quot;tb-body&quot;> <composite:insertChildren/> </div> </div> </composite:implementation> </body></html>
  • 144. Composite Interface <composite:interface> <composite:attribute name=&quot;title&quot; required=&quot;true&quot;/> </composite:interface>
  • 145. Component Usage <html … xmlns:demo= &quot;http://java.sun.com/jsf/composite/demo&quot;> <body> <demo:titleBorder title=&quot;My Favorite Greeting&quot;> Hello, World! </demo:titleBorder> </body> </html>
  • 146. Wicket Custom Components
    • We have already seen several custom components
      • Think event handling
    • Can also define components with custom markup
    • Very similar to page
    • HTML/Java split
    • Java extends Panel or Border (not WebPage)
  • 147. TitleBorder.html <html ... ><body> <wicket:border> <div class=&quot;tb-root&quot;> <div class=&quot;tb-title&quot; wicket:id=&quot;titleLabel&quot;>Title</div> <div class=&quot;tb-body&quot;> <wicket:body/> </div> </div> </wicket:border> </body></html>
  • 148. TitleBorder.java public class TitleBorder extends Border { public TitleBorder(String id) { super(id); add(new Label(&quot;titleLabel&quot;, new PropertyModel(this, &quot;title&quot;))); } // Accessors private String title; }
  • 149. Component Usage <!-- HTML --> <div wicket:id=&quot;titleBorder&quot;> Hello, World! </div> // Java add(new TitleBorder(&quot;titleBorder&quot;));
  • 150. Tapestry Custom Components
    • Again, similar to page
    • TML/Java split
    • Java component is a POJO
    • Located in app-package/components directory
  • 151. TitleBorder.tml <div class=&quot;tb-root&quot; ... > <div class=&quot;tb-title&quot;> ${title} </div> <div class=&quot;tb-body&quot;> <t:body/> </div> </div>
  • 152. TitleBorder.java public class TitleBorder { @Property @Parameter(required=true, defaultPrefix=BindingConstants.LITERAL) private String title; }
  • 153. Component Usage <t:titleborder t:title=&quot;My Favorite Greeting&quot;> Hello, World! </t:titleborder>
  • 154. Custom Component Wrap Up
    • JSF custom component development became much, much simpler in 2.0
    • Composite components provide ease of use previously only available in other frameworks
    • Further simplifications possible?
      • Composite components
      • Java-based components
  • 155.
    • Wrap Up
  • 156. So Much To Do, So Little Time
    • Many other possible points of comparison
      • Performance
      • Tooling
      • Testing
      • I18N
      • Persistence
      • REST
      • Extensions
      • Community
    • Other interesting frameworks too!
    • Presentation 2.0 :-)
  • 157. Conclusion
    • Some differences are fundamental
    • Interesting to see many similarities too
    • Looking outward: good exercise
    • Good to see historical areas of difficulty addressed by JSF 2.0.
    • JSF2.next: Keep the progress coming!