SlideShare a Scribd company logo
Component Framework Primer for JSF Users Andy Schwartz | Oracle Corporation
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)
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
Why Wicket and Tapestry? Similar in scope to JSF Popular choices Many areas of overlap Different approaches Interesting comparisons Plenty of lessons to learn
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 :-)
Agenda Hello, Frameworks! Event Handling Ajax Navigation Input Processing Custom components Wrap up
Hello, JSF!
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
JSF Vision Swing-like component/event model Declarative component tree specification Integration with existing standards Split logical (components) and physical (markup) Tooling Extensibility
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
Saying Hello (JSF)
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>
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>
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
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
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
A Simple Binding <h:outputText  value=&quot;#{sessionScope.user.firstName}&quot;/>
Implicit Objects Bindings have access implicit objects/scopes Servlet-related scopes: applicationScope sessionScope requestScope JSF-specific scopes viewScope flash component Many more objects exposed
Managed Beans POJOs Named Scoped Container-managed
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>
Managed Bean Registration @ManagedBean @SessionScoped public class User { public String getFirstName() { … } }
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;/>
Hello, Wicket!
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)
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
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
Saying Hello (Wicket)
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>
Grunge: web.xml <init-param> <param-name> applicationClassName </param-name> <param-value> org.demo.wicket.HelloApplication </param-value> </init-param>
My First Wicket Application public class HelloApplication extends WebApplication { @Override public Class<Hello> getHomePage() { return Hello.class; } }
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>
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;)); } }
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.
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
What is a Wicket Model? Wicket models bind domain layer objects to components. (Similar to EL ValueExpressions in JSF)
IModel Contract T getObject() void setObject(T object)
Components and Models IModel<?> getDefaultModel() Most components read from model. Some components write to model.
Simple Model Model class implements IModel Stores model object locally We have been using it already
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;)));
Static Model Simple Models are static. // This is static: add(new Label(&quot;random&quot;,  new Model<Double>(Math.random()) ));
Dynamic Model Override getObject() for dynamic. // This is dynamic: add(new Label(&quot;reallyRandom&quot;,  new Model<Double>() { public Double getObject() { return Math.random(); } }));
Some More Models PropertyModel CompoundPropertyModel LoadableDetachableModel ResourceModel
Hello, Tapestry!
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)
Tapestry Vision Similar separation of markup/logic Convention over Configuration Inversion of Control POJOs/annotations Performance
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
Saying Hello (Tapestry)
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>
Grunge: web.xml <context-param> <param-name> tapestry.app-package </param-name> <param-value> org.example.tapestry </param-value> </context-param>
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>
My First Tapestry Page (Java) public class Index { @Property private String name; }
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
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
Take 2: t:id
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>
Take 2: Java public class Index { @Property private String name; @Component( parameters={&quot;value=name&quot;}) private TextOutput nameOutput; }
Take 3: t:type
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>
Facelets Flashback <!-- Remember this? --> <span jsfc=&quot;h:outputText&quot;  value=&quot;#{name}&quot;>Foo</span>!
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)
Property Expressions <!-- Component parameter --> <div><t:textoutput t:value=&quot;user.name&quot;/></div> <!-- Template expansion --> <div>${user.name}</div>
Binding Expressions Parameters can bind to other types of values Prefix identifies binding type: prop literal asset context component message
Binding Expressions <!-- Property Binding--> Hello, <t:textoutput t:value=&quot;name&quot;/>! <!-- Literal Binding--> Hello, <t:textoutput t:value=&quot;literal:World&quot;/>!
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
Some More Thoughts Implicit per-page Java object is convenient Possible to simulate with JSF (viewScope bean) Consider formalizing this in JSF?
Event Handling
JSF Event Handling Inspired by Swing Event Model Listeners registered on components Components fire events Declarative: listeners referenced via EL
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>
JSF Event Handling @ManagedBean @SessionScoped public class Counter { public int getCount() { return count; } public void increment() { count++; } private int count; }
Wicket Event Handling Components expose event-specific hooks Subclasses override to receive notifications
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>
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; }
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()
Tapestry Event Handling Naming Conventions Annotations
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>
Tapestry Event Handling public class Events { @Persist @Property private int count; // Called when any form is submitted void onSubmit() { count++; } }
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++; }
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++ }
Tapestry Event Handling Component-specific events before form Global events before component-specific ActionLink provides form/POST-free events
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
Ajax
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
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>
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>
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
Wicket Ajax Ajax Components Behaviors
Wicket Ajax AjaxButton button = new AjaxButton(&quot;button&quot;) { @Override public void onSubmit( AjaxRequestTarget target , Form form) { count++; if (target != null) { target.addComponent(label); } }});
Wicket Ajax label = new Label(&quot;count&quot;, …); label. setOutputMarkupId(true);
Wicket Ajax Many convenience components, behaviors Fallback behavior: AjaxFallbackLink setOutputMarkupPlaceholderTag() Ajax debug window
Tapestry Ajax Ajax Zones Mixins
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>
Tapestry Ajax public class Ajax { @InjectComponent private Zone countZone; Object onSubmitFromForm1() { return countZone.getBody(); } }
Tapestry Ajax Zone supported by Form, ActionLink, EventLink MultiZoneUpdate Mixins: autocomplete
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
Navigation
JSF Navigation Traditional: POST-based navigation POST triggers action Action determines outcome Outcome mapped to target view
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;; } }
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>
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
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; ; } }
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
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;/>
Wicket Navigation Programmatic navigation: setResponsePage() Class vs. instance
Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { setResponsePage(PageB.class); } };
Wicket Navigation Button button1 = new Button(&quot;button1&quot;) { public void onSubmit() { PageB pageB = new PageB(); // Configure PageB instance… setResponsePage(pageB); } }; Wicket Navigation
Wicket Navigation Direct navigation also supported BookmarkablePageLink wicket:link
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));
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>
Tapestry Navigation Programmatic navigation: onSubmit() return Like Wicket, navigate to class or instance Instance page injected
Tapestry Navigation public class PageA { Object onSubmitFromForm1() { return PageB.class; } }
Tapestry Navigation public class PageA { @InjectPage private PageB pageB; Object onSubmitFromForm1() { // Configure pageB instance... return pageB; } }
Tapestry Navigation Direct navigation also supported t:pageLink
Tapestry Navigation <t:pagelink t:page=&quot;PageB&quot;>Go</t:pagelink>
Navigation Wrap Up JSF 2.0 enhancements simplify navigation String outcomes vs. class/instance Introduce class/instance support in JSF? Redirect defaults
Input Processing
JSF Input Processing EditableValueHolder lifecycle Decode Conversion Validation Update model Value referenced via value expression
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; }
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
JSF Conversion <h:inputText value=&quot;#{user.age}&quot;> <f:convertNumber integerOnly=&quot;true&quot;/> </h:inputText>
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
JSF Validation <h:inputText value=&quot;#{user.age}&quot;> <f:validateLongRange minimum=&quot;18&quot;/> </h:inputText>
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>
Wicket Input Processing Similar lifecycle to JSF Required field validation Conversion Validation Push to model onSubmit/onError Value referenced via Model contract
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;)));
Wicket Conversion IConverter contract, similar to JSF Converter Converts to/from string Default converters Type derived or hinted Custom converters Override getConverter()
Wicket Validation IValidator, similar to JSF Validator Validators attached programmatically
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)));
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
Tapestry Input Processing Similar lifecycle to JSF, Wicket Conversion Validation Push to model onSuccess/onFailure Value referenced via property expressions
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; }
Tapestry Conversion FieldTranslator, similar to Converter/IConverter Event-based conversion toclient parseclient
Tapestry Conversion Events public class Input { String onToClientFromAge() { // Return String representation of age } Object onParseClientFromAge(String input) { // Return converted representation of age } }
Tapestry Validation FieldValidator, similar to Validator/Ivalidator Constraints attached via component parameters Event and annotation-based validation
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;/>
Event-Based Validation void onValidateFromAge(Integer value) throws ValidationException { if (value < 18)  throw new ValidationException(&quot;Too young!&quot;); }
Anntation-Based Validation public class Input { @Property @Validate(&quot;required,min=18&quot;) private int age; }
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
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
Custom Components
JSF: Old School (Java) Java class (extends UIComponent) Renderer class Tag class faces-config.xml tld
JSF: New School (Java) Annotations replace faces-cofig.xml Default Facelets handlers replace Tag class taglib.xml replaces tld
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
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>
Composite Interface <composite:interface> <composite:attribute name=&quot;title&quot; required=&quot;true&quot;/> </composite:interface>
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>
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)
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>
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; }
Component Usage <!-- HTML --> <div wicket:id=&quot;titleBorder&quot;> Hello, World! </div> // Java add(new TitleBorder(&quot;titleBorder&quot;));
Tapestry Custom Components Again, similar to page TML/Java split Java component is a POJO Located in app-package/components directory
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>
TitleBorder.java public class TitleBorder { @Property @Parameter(required=true, defaultPrefix=BindingConstants.LITERAL) private String title;  }
Component Usage <t:titleborder t:title=&quot;My Favorite Greeting&quot;> Hello, World! </t:titleborder>
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
Wrap Up
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 :-)
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!

More Related Content

What's hot (20)

PDF
Jsf intro
vantinhkhuc
 
PPT
JSF Component Behaviors
Andy Schwartz
 
PPT
Struts N E W
patinijava
 
PPTX
Introduction to jsf 2
yousry ibrahim
 
PPTX
9. java server faces
AnusAhmad
 
ODP
Spring Portlet MVC
John Lewis
 
PPT
Spring MVC
yuvalb
 
ODP
Sprint Portlet MVC Seminar
John Lewis
 
PDF
Boston 2011 OTN Developer Days - Java EE 6
Arun Gupta
 
PPT
Unified Expression Language
BG Java EE Course
 
PPTX
Introduction to JSF
SoftServe
 
PPT
Ibm
techbed
 
PPTX
Java Server Faces + Spring MVC Framework
Guo Albert
 
PPT
Struts,Jsp,Servlet
dasguptahirak
 
PPT
Web Applications and Deployment
BG Java EE Course
 
PPT
Jsp ppt
Vikas Jagtap
 
PPTX
Jsf presentation
Ashish Gupta
 
PPT
What's new and exciting with JSF 2.0
Michael Fons
 
PPT
Struts Introduction Course
guest764934
 
Jsf intro
vantinhkhuc
 
JSF Component Behaviors
Andy Schwartz
 
Struts N E W
patinijava
 
Introduction to jsf 2
yousry ibrahim
 
9. java server faces
AnusAhmad
 
Spring Portlet MVC
John Lewis
 
Spring MVC
yuvalb
 
Sprint Portlet MVC Seminar
John Lewis
 
Boston 2011 OTN Developer Days - Java EE 6
Arun Gupta
 
Unified Expression Language
BG Java EE Course
 
Introduction to JSF
SoftServe
 
Ibm
techbed
 
Java Server Faces + Spring MVC Framework
Guo Albert
 
Struts,Jsp,Servlet
dasguptahirak
 
Web Applications and Deployment
BG Java EE Course
 
Jsp ppt
Vikas Jagtap
 
Jsf presentation
Ashish Gupta
 
What's new and exciting with JSF 2.0
Michael Fons
 
Struts Introduction Course
guest764934
 

Similar to Component Framework Primer for JSF Users (20)

PDF
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Arun Gupta
 
PDF
JSF 2.0 Preview
Skills Matter
 
PDF
Apache Wicket: 10 jaar en verder - Martijn Dashorst
NLJUG
 
PDF
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Arun Gupta
 
PDF
The State of Wicket
Martijn Dashorst
 
PPTX
JSF2
Alex Tumanoff
 
PDF
JavaServer Faces 2.0 - JavaOne India 2011
Arun Gupta
 
PDF
Life outside WO
WO Community
 
PPT
Wicket Introduction
Eyal Golan
 
PPTX
Modern Java Web Development
zenyk
 
PDF
Web Applications of the future: Combining JEE6 & JavaFX
Paul Bakker
 
PDF
Tapestry In Action For Real
Skills Matter
 
PDF
Ajax, JSF, Facelets, Eclipse & Maven tutorials
Raghavan Mohan
 
PPT
Server-side Technologies in Java
Anirban Majumdar
 
PDF
JSF 2.2 Input Output JavaLand 2015
Edward Burns
 
PPT
Jsfsunum
cagataycivici
 
PDF
Apache Wicket Web Framework
Luther Baker
 
PPT
Rich faces
BG Java EE Course
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Arun Gupta
 
JSF 2.0 Preview
Skills Matter
 
Apache Wicket: 10 jaar en verder - Martijn Dashorst
NLJUG
 
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Arun Gupta
 
The State of Wicket
Martijn Dashorst
 
JavaServer Faces 2.0 - JavaOne India 2011
Arun Gupta
 
Life outside WO
WO Community
 
Wicket Introduction
Eyal Golan
 
Modern Java Web Development
zenyk
 
Web Applications of the future: Combining JEE6 & JavaFX
Paul Bakker
 
Tapestry In Action For Real
Skills Matter
 
Ajax, JSF, Facelets, Eclipse & Maven tutorials
Raghavan Mohan
 
Server-side Technologies in Java
Anirban Majumdar
 
JSF 2.2 Input Output JavaLand 2015
Edward Burns
 
Jsfsunum
cagataycivici
 
Apache Wicket Web Framework
Luther Baker
 
Rich faces
BG Java EE Course
 
Ad

Recently uploaded (20)

PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Biography of Daniel Podor.pdf
Daniel Podor
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Ad

Component Framework Primer for JSF Users

  • 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
  • 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
  • 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;/>
  • 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
  • 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
  • 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
  • 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
  • 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; }
  • 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?
  • 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
  • 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
  • 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
  • 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
  • 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!