JavaServer Faces 2.0 vs. Tapestry 5 A Head-to-Head Comparison - - PowerPoint PPT Presentation

javaserver faces 2 0 vs tapestry 5
SMART_READER_LITE
LIVE PREVIEW

JavaServer Faces 2.0 vs. Tapestry 5 A Head-to-Head Comparison - - PowerPoint PPT Presentation

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


slide-1
SLIDE 1

JavaServer Faces 2.0 vs. Tapestry 5

A Head-to-Head Comparison

Igor Drobiazko Apache Software Foundation 69

slide-2
SLIDE 2

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

slide-3
SLIDE 3
slide-4
SLIDE 4

AGENDA

> Introduction > Error Reporting > Navigation > Validation & Conversion > Creating Components > Internationalization > Around JSF and Tapestry

slide-5
SLIDE 5

History of Web Frameworks

2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011

1.0 1.0 1.0 1.0

slide-6
SLIDE 6

History of Web Frameworks

2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011

3.0 1.0 1.0 4.0 5.0 1.0 1.0 1.0 1.0 2.0 2.0 1.0 1.0 5.1 5.2 1.0

slide-7
SLIDE 7

JavaServer Faces 2.0 vs Tapestry 5 JavaServer Faces 2.0 Tapestry 5 JavaServer Faces 2.0

VS.

slide-8
SLIDE 8

Model-View-Controller

Model Controller View

slide-9
SLIDE 9

Model-View-Controller

Model Controller View

Servlet / Filter HTML /XHTML POJO

slide-10
SLIDE 10

JSF Pages UserBean.java hello.xhtml

slide-11
SLIDE 11

JSF Pages UserBean.java hello.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 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>

slide-12
SLIDE 12

JSF Pages UserBean.java hello.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 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> @ManagedBean @RequestScoped public class UserBean { public String getHello() { return "Hello, World!"; } }

slide-13
SLIDE 13

JSF Pages UserBean.java hello.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 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> @ManagedBean @RequestScoped public class UserBean { public String getHello() { return "Hello, World!"; } }

http://example.org/hello.xhtml

slide-14
SLIDE 14

Package Strukture

  • rg.example

pages c

  • m

p

  • n

e n t s e r v i c e s m i x i n s

<web-app> <context-param> <param-name>tapestry.app-package</param-name> <param-value>org.example</param-value> </context-param> ... </web-app>

slide-15
SLIDE 15

Tapestry Pages (1/2) Hello.tml Hello.java

slide-16
SLIDE 16

Tapestry Pages (1/2) Hello.tml Hello.java

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html>

slide-17
SLIDE 17

Tapestry Pages (1/2) Hello.tml Hello.java

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> public class Hello { public String getHello() { return "Hello, World!"; } }

slide-18
SLIDE 18

Tapestry Pages (1/2) Hello.tml Hello.java

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> public class Hello { public String getHello() { return "Hello, World!"; } }

slide-19
SLIDE 19

Tapestry Pages (1/2) Hello.tml Hello.java

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body>${hello}</body> </html> public class Hello { public String getHello() { return "Hello, World!"; } }

http://example.org/hello

slide-20
SLIDE 20

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; } }

slide-21
SLIDE 21

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; } }

Convert a request parameter into a Book Generare getter & setter Persist primary key into HTTP session Commit Hibernate transaction Clear persistent fields Inject Hibernate session Redirect to page ShowBooks

slide-22
SLIDE 22

Error Reporting

slide-23
SLIDE 23

JSF 1.x Error Report

slide-24
SLIDE 24

JSF 2.0 Error Report

slide-25
SLIDE 25

Tapestry Error Report

slide-26
SLIDE 26

Navigation

slide-27
SLIDE 27

Tool Friendly Navigation login.xhtml failure.xhtml success.xhtml success failure

slide-28
SLIDE 28

Tool Friendly Navigation login.xhtml failure.xhtml success.xhtml success failure faces-config.xml

slide-29
SLIDE 29

Tool Friendly Navigation login.xhtml failure.xhtml success.xhtml success failure faces-config.xml

<navigation-rule> <from-view-id>/login.xhtml</from-view-id> <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> </navigation-rule>

slide-30
SLIDE 30

Dynamic Navigation login.xhtml success.xhtml

slide-31
SLIDE 31

Dynamic Navigation login.xhtml success.xhtml

<h:form> ... <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form>

slide-32
SLIDE 32

Dynamic Navigation login.xhtml success.xhtml

<h:form> ... <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form>

Login.java

slide-33
SLIDE 33

Dynamic Navigation login.xhtml success.xhtml

<h:form> ... <h:commandButton value= "Login" action="#{login.loginUser}“> </h:form>

Login.java

@ManagedBean @RequestScoped public class Login { public String loginUser() { if(userExists()){ return "success"; } return "failure"; } }

slide-34
SLIDE 34

Developer Friendly Navigation (1/2) Index.tml MyPage.tml

slide-35
SLIDE 35

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

slide-36
SLIDE 36

Developer Friendly Navigation (2/2)

slide-37
SLIDE 37

Developer Friendly Navigation (2/2)

public class Index { @InjectPage private MyPage myPage; Object onAction(){ return myPage; } }

slide-38
SLIDE 38

Developer Friendly Navigation (2/2)

public class Index { Object onAction(){ return "MyPage"; } }

slide-39
SLIDE 39

Developer Friendly Navigation (2/2)

public class Index { Object onAction(){ return MyPage.class; } }

slide-40
SLIDE 40

Developer Friendly Navigation (2/2)

public class Index { Object onAction() throws MalformedURLException { return new URL("http://www.google.com"); } }

slide-41
SLIDE 41

Dynamic Navigation Login.tml Login.java

slide-42
SLIDE 42

Dynamic Navigation Login.tml Login.java

<t:form> <t:textfield value="userName" validate="required"/> ... <input type="submit" value="Register"/> <t:form>

slide-43
SLIDE 43

Dynamic Navigation Login.tml Login.java

<t:form> <t:textfield value="userName" validate="required"/> ... <input type="submit" value="Register"/> <t:form> public class Login { @Property @Persist private String userName; ... Object onSuccess() { return UserProfile.class; } }

slide-44
SLIDE 44

Dynamic Navigation Login.tml UserProfile.tml Login.java

<t:form> <t:textfield value="userName" validate="required"/> ... <input type="submit" value="Register"/> <t:form>

UserProfile.java

public class Login { @Property @Persist private String userName; ... Object onSuccess() { return UserProfile.class; } }

slide-45
SLIDE 45

Redirect After Post

slide-46
SLIDE 46

Redirect After Post

POST

HTTP/1.1 303 See Other GET HTTP/1.1 200 OK

slide-47
SLIDE 47

Redirect After Post login.xhtml

<h:form> ... <h:commandButton value="Login" action="#{login.loginUser}" /> </h:form> @ManagedBean @RequestScoped public class Login { ... public String loginUser() { if(userExists()){ return "success?faces-redirect=true"; } return "failure"; } }

Login.java

slide-48
SLIDE 48

Input Validation

slide-49
SLIDE 49

Validation & Conversion register.xhtml UserBean.java

slide-50
SLIDE 50

Validation & Conversion register.xhtml UserBean.java

< h : f

  • r

m > U s e r N a m e : < h : i n p u t T e x t v a l u e = " # { u s e r B e a n . n a m e } " r e q u i r e d = " t r u e " > < f : v a l i d a t e L e n g t h m i n i m u m = " 3 " m a x i m u m = " 5 " / > < / h : i n p u t T e x t > D a t e

  • f

B i r t h : < h : i n p u t T e x t v a l u e = " # { u s e r B e a n . b i r t h d a y } " > < f : c

  • n

v e r t D a t e T i m e p a t t e r n = " M M

  • d

d

  • y

y " / > < / h : i n p u t T e x t > < h : c

  • m

m a n d B u t t

  • n

v a l u e = " R e g i s t e r " a c t i

  • n

= " r e g i s t e r " / > < / h : f

  • r

m >

slide-51
SLIDE 51

Validation & Conversion register.xhtml UserBean.java

< h : f

  • r

m > U s e r N a m e : < h : i n p u t T e x t v a l u e = " # { u s e r B e a n . n a m e } " r e q u i r e d = " t r u e " > < f : v a l i d a t e L e n g t h m i n i m u m = " 3 " m a x i m u m = " 5 " / > < / h : i n p u t T e x t > D a t e

  • f

B i r t h : < h : i n p u t T e x t v a l u e = " # { u s e r B e a n . b i r t h d a y } " > < f : c

  • n

v e r t D a t e T i m e p a t t e r n = " M M

  • d

d

  • y

y " / > < / h : i n p u t T e x t > < h : c

  • m

m a n d B u t t

  • n

v a l u e = " R e g i s t e r " a c t i

  • n

= " r e g i s t e r " / > < / h : f

  • r

m > @ M a n a g e d B e a n @ S e s s i

  • n

S c

  • p

e d p u b l i c c l a s s U s e r B e a n { p r i v a t e S t r i n g n a m e ; @ F u t u r e p r i v a t e D a t e b i r t h d a y ; @ N

  • t

N u l l @ E m a i l p r i v a t e S t r i n g e m a i l ; }

slide-52
SLIDE 52

Validation & Conversion Register.tml Register.java

slide-53
SLIDE 53

Validation & Conversion Register.tml Register.java

< t : f

  • r

m c l i e n t V a l i d a t i

  • n

= " t r u e " > < t : e r r

  • r

s / > U s e r N a m e : < t : t e x t f i e l d v a l u e = " u s e r . n a m e " v a l i d a t e = " r e q u i r e d , m i n l e n g t h = 3 , m a x l e n g t h = 5 " / > D a t e

  • f

B i r t h : < t : d a t e f i e l d v a l u e = " u s e r . b i r t h d a y " f

  • r

m a t = " M M

  • d

d

  • y

y " / > < i n p u t t y p e = " s u b m i t " v a l u e = " R e g i s t e r " / > < / t : f

  • r

m >

slide-54
SLIDE 54

Validation & Conversion Register.tml Register.java

< t : f

  • r

m c l i e n t V a l i d a t i

  • n

= " t r u e " > < t : e r r

  • r

s / > U s e r N a m e : < t : t e x t f i e l d v a l u e = " u s e r . n a m e " v a l i d a t e = " r e q u i r e d , m i n l e n g t h = 3 , m a x l e n g t h = 5 " / > D a t e

  • f

B i r t h : < t : d a t e f i e l d v a l u e = " u s e r . b i r t h d a y " f

  • r

m a t = " M M

  • d

d

  • y

y " / > < i n p u t t y p e = " s u b m i t " v a l u e = " R e g i s t e r " / > < / t : f

  • r

m > p u b l i c c l a s s R e g i s t e r { @ P r

  • p

e r t y p r i v a t e U s e r u s e r ; p u b l i c v

  • i

d

  • n

V a l i d a t e F

  • r

m ( ) { . . . } }

slide-55
SLIDE 55

JSR 303 User.java

slide-56
SLIDE 56

JSR 303 User.java

p u b l i c c l a s s U s e r { @ V a l i d a t e ( " r e q u i r e d , m i n l e n g t h = 3 , m a x l e n g t h = 5 " ) p r i v a t e S t r i n g n a m e ; @ F u t u r e p r i v a t e D a t e b i r t h d a y ; @ N

  • t

N u l l @ E m a i l p r i v a t e S t r i n g e m a i l ; }

slide-57
SLIDE 57

Components

slide-58
SLIDE 58

Composite Components hellocomponent.xhtml main.xhtml

slide-59
SLIDE 59

Composite Components hellocomponent.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite"> <cc:interface> <cc:attribute name="firstname" required="true"/> </cc:interface> <cc:implementation> Hello, <h:outputText value="#{cc.attrs.firstname}" />! </cc:implementation> </html>

main.xhtml

slide-60
SLIDE 60

Composite Components hellocomponent.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite"> <cc:interface> <cc:attribute name="firstname" required="true"/> </cc:interface> <cc:implementation> Hello, <h:outputText value="#{cc.attrs.firstname}" />! </cc:implementation> </html>

main.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:lib="http://java.sun.com/jsf/composite/mylib"> <h:body> <lib:hellocomponent firstname="Igor"/> </h:body> </html>

slide-61
SLIDE 61

Composite Components hellocomponent.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite"> <cc:interface> <cc:attribute name="firstname" required="true"/> </cc:interface> <cc:implementation> Hello, <h:outputText value="#{cc.attrs.firstname}" />! </cc:implementation> </html>

main.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:lib="http://java.sun.com/jsf/composite/mylib"> <h:body> <lib:hellocomponent firstname="Igor"/> </h:body> </html>

slide-62
SLIDE 62

Noncomposite Components (1/2) HelloComponent.java hello.taglib.xhtml

slide-63
SLIDE 63

Noncomposite Components (1/2) HelloComponent.java hello.taglib.xhtml

@FacesComponent public class HelloComponent extends UIComponentBase { public void encodeAll(FacesContext context) throws IOException { ResponseWriter writer = context.getResponseWriter(); String firstname = (String) this.getAttributes().get("firstname"); writer.writeText("Hello, " + firstname, null); } public String getFamily() { return null; } }

slide-64
SLIDE 64

Noncomposite Components (2/2) hello.taglib.xhtml main.xhtml

slide-65
SLIDE 65

Noncomposite Components (2/2) hello.taglib.xhtml

<facelet-taglib> <namespace>http://example.org/lib</namespace> <tag> <tag-name>hello</tag-name> <component> <component-type>HelloComponent</component-type> </component> </tag> </facelet-taglib>

main.xhtml

slide-66
SLIDE 66

Noncomposite Components (2/2) hello.taglib.xhtml

<facelet-taglib> <namespace>http://example.org/lib</namespace> <tag> <tag-name>hello</tag-name> <component> <component-type>HelloComponent</component-type> </component> </tag> </facelet-taglib>

main.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:lib="http://example.org/lib"> <h:body> <lib:hello firstname="Igor"/> </h:body> </html>

slide-67
SLIDE 67

Noncomposite Components (2/2) hello.taglib.xhtml

<facelet-taglib> <namespace>http://example.org/lib</namespace> <tag> <tag-name>hello</tag-name> <component> <component-type>HelloComponent</component-type> </component> </tag> </facelet-taglib>

main.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:lib="http://example.org/lib"> <h:body> <lib:hello firstname="Igor"/> </h:body> </html>

slide-68
SLIDE 68

Tapestry Components HelloComponent.tml HelloComponent.java

slide-69
SLIDE 69

Tapestry Components HelloComponent.tml HelloComponent.java

<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> Hello, ${name}! </div>

slide-70
SLIDE 70

Tapestry Components HelloComponent.tml HelloComponent.java

<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> Hello, ${name}! </div> public class HelloComponent { @Parameter(required=true) @Property private String name; }

slide-71
SLIDE 71

Tapestry Components HelloComponent.tml HelloComponent.java

<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> Hello, ${name}! </div> public class HelloComponent { @Parameter(required=true) @Property private String name; }

MyPage.tml

slide-72
SLIDE 72

Tapestry Components HelloComponent.tml HelloComponent.java

<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> Hello, ${name}! </div> public class HelloComponent { @Parameter(required=true) @Property private String name; }

MyPage.tml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <t:helloComponent name="literal:Igor"/> </html>

slide-73
SLIDE 73

Component Rendering

slide-74
SLIDE 74

Component Rendering

public class HelloComponent { @Parameter private String name; boolean beginRender(MarkupWriter writer) { writer.element("div"); writer.write("Hello, " + name); writer.end(); return false; } }

slide-75
SLIDE 75

Component Rendering

public class HelloComponent { @Parameter private String name; @BeginRender boolean foo(MarkupWriter writer) { writer.element("div"); writer.write("Hello, " + name); writer.end(); return false; } }

slide-76
SLIDE 76

Component Rendering

public class HelloComponent { @Parameter private String name; @BeginRender void foo(MarkupWriter writer) { writer.element( "div"); } @BeforeRenderBody void bar(MarkupWriter writer){ writer.write( "Hello, " + name); } @AfterRender void baz(MarkupWriter writer) { writer.end(); } }

slide-77
SLIDE 77

Query Parameters QueryParameterDemo.java

/app1/queryparameterdemo.xhtml?x=97&y=hello

slide-78
SLIDE 78

Query Parameters

@FacesComponent(value="QueryParameterDemo") public class QueryParameterDemo extends UIInput { public void decode(FacesContext context) { ExternalContext externalContext = context.getExternalContext(); Map<String, String> requestMap = externalContext.getRequestParameterMap(); Double x = Double.valueOf((String) requestMap.get("x")); String y = (String) requestMap.get("y"); System.err.println("x: " + x); System.err.println("y: " + y); } }

QueryParameterDemo.java

/app1/queryparameterdemo.xhtml?x=97&y=hello

slide-79
SLIDE 79

Query Parameters QueryParameterDemo.java

/app1/queryparameterdemo:action?x=97&y=hello

slide-80
SLIDE 80

Query Parameters

public class QueryParameterDemo { void onAction(@QueryParameter(value = "x") double x, @QueryParameter(value = "y") String y) { System.err.println("x: " + x); System.err.println("y: " + y); } }

QueryParameterDemo.java

/app1/queryparameterdemo:action?x=97&y=hello

slide-81
SLIDE 81

State Management

public class UIOutput extends UIComponentBase implements ValueHolder { public Object getValue() { return getStateHelper().eval(PropertyKeys.value); } public void setValue(Object value) { getStateHelper().put(PropertyKeys.value, value); } ... } public class MyPage { @SessionState private User user; @Persist @Propety private Integer value; }

slide-82
SLIDE 82

Internationalization

slide-83
SLIDE 83

Localized Pages mypage.xhtml

slide-84
SLIDE 84

Localized Pages mypage.xhtml

<f:loadBundle basename="com.example.Resources" var="bundle"> ... <h:outputText value="#{bundle.welcome-message"/> <h:outputText value="#{bundle2.another-message"/>

slide-85
SLIDE 85

Localized Pages com.example.Resources.properties mypage.xhtml

<f:loadBundle basename="com.example.Resources" var="bundle"> ... <h:outputText value="#{bundle.welcome-message"/> <h:outputText value="#{bundle2.another-message"/>

slide-86
SLIDE 86

Localized Pages com.example.Resources.properties mypage.xhtml

<f:loadBundle basename="com.example.Resources" var="bundle"> ... <h:outputText value="#{bundle.welcome-message"/> <h:outputText value="#{bundle2.another-message"/>

faces-config.xml

slide-87
SLIDE 87

Localized Pages com.example.Resources.properties mypage.xhtml

<f:loadBundle basename="com.example.Resources" var="bundle"> ... <h:outputText value="#{bundle.welcome-message"/> <h:outputText value="#{bundle2.another-message"/>

faces-config.xml

<application> <resource-bundle> <base-name>com.example.ResourceBundle</base-name> <var>bundle2</var> </resource-bundle> </application>

slide-88
SLIDE 88

Message Catalog MyPage.java MyPage.tml

slide-89
SLIDE 89

Message Catalog MyPage.java MyPage.tml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> ${messages:welcome-message} ${prop:welcomeMessage} </body> </html>

slide-90
SLIDE 90

Message Catalog MyPage.java MyPage.tml MyPage.properties MyPage_de.properties

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> ${messages:welcome-message} ${prop:welcomeMessage} </body> </html>

slide-91
SLIDE 91

Message Catalog MyPage.java MyPage.tml MyPage.properties MyPage_de.properties app.properties

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> ${messages:welcome-message} ${prop:welcomeMessage} </body> </html>

slide-92
SLIDE 92

Message Catalog MyPage.java MyPage.tml MyPage.properties MyPage_de.properties app.properties

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> ${messages:welcome-message} ${prop:welcomeMessage} </body> </html> public class MyPage { @Inject private Messages messages; public String getWelcomeMessage() { return messages.get("welcome-message"); } }

slide-93
SLIDE 93

Localizable Templates MyPage.java MyPage.tml MyPage_jp.tml MyPage_iw.tml

slide-94
SLIDE 94

Around JSF

slide-95
SLIDE 95

Around Tapestry

Tapestry JumpStart Tapestry360

slide-96
SLIDE 96

Igor Drobiazko HSBC INKA http://tapestry5.de drobiazko@apache.org