JavaServer Faces 2.0 vs. Tapestry 5 A Head-to-Head Comparison Igor Drobiazko Apache Software Foundation 69
About Me > Software Engineer at HSBC INKA > Apache Tapestry Committer > Tapestry Project Management Committee > Tapestry Envangelist > Book Author & Speaker > http://tapestry5.de > drobiazko@apache.org
AGENDA > Introduction > Error Reporting > Navigation > Validation & Conversion > Creating Components > Internationalization > Around JSF and Tapestry
History of Web Frameworks 2008 2009 2010 2011 2002 2003 2004 2005 2006 2007 2000 2001 1.0 1.0 1.0 1.0
4.0 History of Web Frameworks 5.1 5.2 5.0 1.0 1.0 1.0 2008 2009 2010 2011 2002 2003 2004 2005 2006 2007 2000 2001 3.0 1.0 2.0 1.0 2.0 1.0 1.0 1.0 1.0
JavaServer Faces 2.0 vs Tapestry 5 VS. JavaServer Faces 2.0 Tapestry 5 JavaServer Faces 2.0
Model-View-Controller Model View Controller
Model-View-Controller POJO Model View Controller HTML /XHTML Servlet / Filter
JSF Pages hello.xhtml UserBean.java
<html xmlns="http://www.w3.org/1999/xhtml" JSF Pages xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:body> <h:outputText value="#{userBean.hello} “/> </h:body> </html> hello.xhtml UserBean.java
<html xmlns="http://www.w3.org/1999/xhtml" JSF Pages xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:body> <h:outputText value="#{userBean.hello} “/> </h:body> </html> hello.xhtml UserBean.java @ManagedBean @RequestScoped public class UserBean { public String getHello() { return "Hello, World!"; } }
<html xmlns="http://www.w3.org/1999/xhtml" JSF Pages xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:body> <h:outputText value="#{userBean.hello} “/> </h:body> </html> http://example.org/hello.xhtml hello.xhtml UserBean.java @ManagedBean @RequestScoped public class UserBean { public String getHello() { return "Hello, World!"; } }
<web-app> Package Strukture <context-param> <param-name>tapestry.app-package</param-name> <param-value>org.example</param-value> </context-param> ... </web-app> org.example e n t c e s x i n s o m p o n s e r v i m i c pages
Tapestry Pages (1/2) Hello.java Hello.tml
Tapestry Pages (1/2) <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> Hello.java Hello.tml
Tapestry Pages (1/2) <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> Hello.java Hello.tml public class Hello { public String getHello() { return "Hello, World!"; } }
Tapestry Pages (1/2) <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> Hello.java Hello.tml public class Hello { public String getHello() { return "Hello, World!"; } }
Tapestry Pages (1/2) <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> Hello.java Hello.tml http://example.org/hello public class Hello { public String getHello() { return "Hello, World!"; } }
Page Classes public class EditBook { @PageActivationContext @Property @Persist("entity") private Book book; @Inject private Session session; @CommitAfter @DiscardAfter Object onSuccess() { session.update(book); return ShowBooks.class; } }
Page Classes public class EditBook { Convert a request parameter into a Book @PageActivationContext @Property Generare getter & setter @Persist("entity") private Book book; Persist primary key into HTTP session @Inject Inject Hibernate session private Session session; Commit Hibernate transaction @CommitAfter @DiscardAfter Clear persistent fields Object onSuccess() { session.update(book); return ShowBooks.class; Redirect to page ShowBooks } }
Error Reporting
JSF 1.x Error Report
JSF 2.0 Error Report
Tapestry Error Report
Navigation
Tool Friendly Navigation login.xhtml success failure success.xhtml failure.xhtml
Tool Friendly Navigation login.xhtml success failure success.xhtml failure.xhtml faces-config.xml
Tool Friendly Navigation login.xhtml success failure <navigation-rule> <from-view-id>/login.xhtml</from-view-id> success.xhtml failure.xhtml <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/success.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/failure.xhtml</to-view-id> </navigation-case> faces-config.xml </navigation-rule>
Dynamic Navigation login.xhtml success.xhtml
<h:form> ... Dynamic Navigation <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form> login.xhtml success.xhtml
<h:form> ... Dynamic Navigation <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form> login.xhtml success.xhtml Login.java
<h:form> ... Dynamic Navigation <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form> login.xhtml success.xhtml @ManagedBean @RequestScoped public class Login { public String loginUser() { if(userExists()){ Login.java return "success"; } return "failure"; } }
Developer Friendly Navigation (1/2) Index.tml MyPage.tml
Developer Friendly Navigation (1/2) <a t:type="PageLink" page="MyPage">Go To MyPage</a> <a t:type="ActionLink">Go To MyPage</a> Index.tml MyPage.tml
Developer Friendly Navigation (2/2)
Developer Friendly Navigation (2/2) public class Index { @InjectPage private MyPage myPage; Object onAction(){ return myPage; } }
Developer Friendly Navigation (2/2) public class Index { Object onAction(){ return "MyPage"; } }
Developer Friendly Navigation (2/2) public class Index { Object onAction(){ return MyPage.class; } }
Developer Friendly Navigation (2/2) public class Index { Object onAction() throws MalformedURLException { return new URL("http://www.google.com"); } }
Dynamic Navigation Login.tml Login.java
<t:form> <t:textfield value="userName" validate="required"/> Dynamic Navigation ... <input type="submit" value="Register"/> <t:form> Login.tml Login.java
<t:form> <t:textfield value="userName" validate="required"/> Dynamic Navigation ... <input type="submit" value="Register"/> <t:form> Login.tml public class Login { @Property @Persist private String userName; ... Login.java Object onSuccess() { return UserProfile.class; } }
<t:form> <t:textfield value="userName" validate="required"/> Dynamic Navigation ... <input type="submit" value="Register"/> <t:form> UserProfile.tml Login.tml public class Login { @Property @Persist private String userName; ... Login.java UserProfile.java Object onSuccess() { return UserProfile.class; } }
Redirect After Post
Redirect After Post POST HTTP/1.1 303 See Other GET HTTP/1.1 200 OK
Redirect After Post <h:form> ... <h:commandButton value="Login" action="#{login.loginUser}" /> </h:form> login.xhtml @ManagedBean @RequestScoped public class Login { ... public String loginUser() { if(userExists()){ return "success?faces-redirect=true"; Login.java } return "failure"; } }
Input Validation
Validation & Conversion register.xhtml UserBean.java
Recommend
More recommend