Go Fullstack: JSF for public sites
Michael Kurz | IRIAN
Agenda

• Motivation
• Architecture with/without EE 6 container
• Putting the pieces together (CDI and CODI)
• JSF and GET-Requests
• RESTful URLs with JSF and PrettyFaces
• Demonstrations and examples
Motivation

• http://scientific-consensus.com
• From GWT to JavaServer Faces
• Lightweight Java EE 6 architecture
• Does JSF really support HTTP GET?
Architecture and Technology Stack

   Architecture   With EE 6 container   No EE 6 container


   Presentation    JSF, CDI, CODI       JSF, CDI, CODI



     Service          EJB, CDI             CDI, CODI



   Data access        EJB, JPA          CDI, CODI, JPA
MyFaces Extensions CDI

• Portable extension of CDI
• Simplifies development with CDI and JSF
• Several modules:
 • JSF 1.2 and 2.0
 • JPA, bean validation...
• Works with:
 • CDI: OpenWebBeans, Weld
 • JSF: MyFaces, Mojarra (1.2 und 2.0)
• Watch out Apache DeltaSpike
Management of Persistence Context

• With Java EE container (EJB)

 @javax.ejb.Stateless
 public class CustomerRepository {
   @PersistenceContext private EntityManager em;
 }


• Without Java EE container (CDI + CODI)

 @ApplicationScoped
 public class CustomerRepository {
   @Inject private EntityManager em;
 }
Transaction Management

• With Java EE container
 • Transactions managed by container (@TransactionAttribute)
• Without Java EE container (CDI only)
 • Transactions managed by CODI

 @ApplicationScoped
 public class CustomerService {
   @Inject
   private CustomerRepository customerRepository;

     @Transactional
     public void saveUser(User user) {...}
 }
Demonstration




• Architecture with CDI and CODI




Beispiel: https://github.com/jsflive/mymail-get
The Web versus JSF




                 vs.
      HTTP GET         HTTP POST
JSF requests

• HTTP requests in classic JSF

            page1.xhtml               page2.xhtml               page3.xhtml
    GET                      POST                      POST

          /faces/page1.jsf          /faces/page1.jsf          /faces/page2.jsf


• Problems with HTTP POST:
 • Page reload problematic
 • URL in browser one step behind
 • Lack of bookmarkability/direct linking
• JSF 2: h:link, h:button and view parameters
JSF 2: Navigation with h:link and h:button

• Navigation target in attribut outcome
 <h:link outcome="/page1.xhtml" value="Page 1"/>
 <h:link outcome="/page2.xhtml" value="Page 2">
   <f:param name="para" value="1"/>
 </h:link>
 <h:button outcome="/page3.xhtml" value="Page 3"/>

• Renders link oder button (h:form not necessary)
 <a href="/page1.jsf">Page 1</a>
 <a href="/page2.jsf?para=1">Page 2</a>
 <input type="button" value="Page 3"
     onclick="window.location.href = '/pag3.jsf'"/>
JSF 2: View Parameters

• Bind request parameters to bean properties
• Tag f:viewParam in f:metadata

 <f:metadata>
   <f:viewParam name="id" value="#{myBean.id}"/>
 </f:metadata>

                                                   Converted and
 @Named @RequestScoped                               validated
 public class MyBean {
   private long id;
   public long getId() {return id;}
   public void setId(long id) {this.id = id;}
 }
What about view actions?

• JSF 2.0 "forgot" about them
• Alternative: PreRenderViewEvent
 <f:event type="preRenderView" listener="#{bean.preRender}"/>


• Alternative: CODI @PreRenderView
• Real view actions part of JSF 2.2

 <f:metadata>
   <f:viewParam name="id" value="#{bean.id}"/>
   <f:viewAction action="#{bean.load}"/>
 </f:metadata>
Post-Redirect-Get with JSF 2

• Request /faces/myPage.xhtml?id=1
 <h:form>
   <h:commandButton action="#{myBean.save}" value="Save"/>
   <h:commandButton value="Cancel" immediate="true"
       action="myPage?faces-redirect=true&amp;
                      faces-include-view-params=true"/>
 </h:form>

 @Named @RequestScoped
 public class MyBean {
   public String save() {
     return "myPage?faces-redirect=true"
            + "&faces-include-view-params=true";
   }
 }
Demonstration




• GET requests with h:link and h:button
• View Parameters
• Post-Redirect-Get with JSF

Beispiel: https://github.com/jsflive/jsf-get02
RESTful URLs



   http://myshop.at/node.html?mode=list&cat=1234




         http://myshop.at/products/books
Why RESTful URLs?

• Readability
• Search Engine Optimization (SEO)
• Confidence
• Looks prettier
RESTful URLs for JSF

• PrettyFaces: RESTful URLS for JSF
 • By OCPsoft, Open Source
• Features:
 • URL Rewriting
 • Enhanced navigation
 • Page actions
 • Seamless integration into JSF
 • Easy configuration
PrettyFaces: Example 1 (1)

• Remove "JSF parts" of URL



          http://myshop.at/faces/account.xhtml




               http://myshop.at/account
PrettyFaces: Example 1 (2)

• Configuration in pretty-config.xml
 <url-mapping id="account">
   <pattern value="/account"/>
   <view-id value="/faces/account.xhtml"/>
 </url-mapping>


• Annotation based configuration

 @Named @RequestScoped
 @URLMapping(id="account", pattern="/account",
     viewId="/faces/account.xhtml")
 public class AccountPage {}
PrettyFaces: Example 2 (1)

• Map part of URL to parameter



  http://myshop.at/faces/products/details.xhtml?id=123




              http://myshop.at/product/123
PrettyFaces: Example 2 (2)

• Configuration in pretty-config.xml
 <url-mapping id="productDetails">
   <pattern value="/product/#{id}"/>
   <view-id value="/faces/products/details.xhtml"/>
 </url-mapping>


• Path parameter used in view parameter

 <f:metadata>
   <f:viewParam name="id" value="#{bean.id}"/>
 </f:metadata>
 <f:event type="preRenderView" listener="#{bean.preRender}"/>
Demonstration




• PrettyFaces




Beispiel: https://github.com/jsflive/jsf-get03
Conclusion

• Lightweight Architecture with Java EE 6
• JSF 2 simplifies GET support
• PrettyFaces
• Necessary for the intranet?
Curious?




• Kurz, Marinschek, Müllan:
  JavaServer Faces 2.0, dpunkt.Verlag
• IRIAN JSF@Work Online-Tutorial
  http://jsfatwork.irian.at
• JSFlive Weblog
  http://jsflive.wordpress.com

Go Fullstack: JSF for Public Sites (CONFESS 2012)

  • 1.
    Go Fullstack: JSFfor public sites Michael Kurz | IRIAN
  • 2.
    Agenda • Motivation • Architecturewith/without EE 6 container • Putting the pieces together (CDI and CODI) • JSF and GET-Requests • RESTful URLs with JSF and PrettyFaces • Demonstrations and examples
  • 3.
    Motivation • http://scientific-consensus.com • FromGWT to JavaServer Faces • Lightweight Java EE 6 architecture • Does JSF really support HTTP GET?
  • 4.
    Architecture and TechnologyStack Architecture With EE 6 container No EE 6 container Presentation JSF, CDI, CODI JSF, CDI, CODI Service EJB, CDI CDI, CODI Data access EJB, JPA CDI, CODI, JPA
  • 5.
    MyFaces Extensions CDI •Portable extension of CDI • Simplifies development with CDI and JSF • Several modules: • JSF 1.2 and 2.0 • JPA, bean validation... • Works with: • CDI: OpenWebBeans, Weld • JSF: MyFaces, Mojarra (1.2 und 2.0) • Watch out Apache DeltaSpike
  • 6.
    Management of PersistenceContext • With Java EE container (EJB) @javax.ejb.Stateless public class CustomerRepository { @PersistenceContext private EntityManager em; } • Without Java EE container (CDI + CODI) @ApplicationScoped public class CustomerRepository { @Inject private EntityManager em; }
  • 7.
    Transaction Management • WithJava EE container • Transactions managed by container (@TransactionAttribute) • Without Java EE container (CDI only) • Transactions managed by CODI @ApplicationScoped public class CustomerService { @Inject private CustomerRepository customerRepository; @Transactional public void saveUser(User user) {...} }
  • 8.
    Demonstration • Architecture withCDI and CODI Beispiel: https://github.com/jsflive/mymail-get
  • 9.
    The Web versusJSF vs. HTTP GET HTTP POST
  • 10.
    JSF requests • HTTPrequests in classic JSF page1.xhtml page2.xhtml page3.xhtml GET POST POST /faces/page1.jsf /faces/page1.jsf /faces/page2.jsf • Problems with HTTP POST: • Page reload problematic • URL in browser one step behind • Lack of bookmarkability/direct linking • JSF 2: h:link, h:button and view parameters
  • 11.
    JSF 2: Navigationwith h:link and h:button • Navigation target in attribut outcome <h:link outcome="/page1.xhtml" value="Page 1"/> <h:link outcome="/page2.xhtml" value="Page 2"> <f:param name="para" value="1"/> </h:link> <h:button outcome="/page3.xhtml" value="Page 3"/> • Renders link oder button (h:form not necessary) <a href="/page1.jsf">Page 1</a> <a href="/page2.jsf?para=1">Page 2</a> <input type="button" value="Page 3" onclick="window.location.href = '/pag3.jsf'"/>
  • 12.
    JSF 2: ViewParameters • Bind request parameters to bean properties • Tag f:viewParam in f:metadata <f:metadata> <f:viewParam name="id" value="#{myBean.id}"/> </f:metadata> Converted and @Named @RequestScoped validated public class MyBean { private long id; public long getId() {return id;} public void setId(long id) {this.id = id;} }
  • 13.
    What about viewactions? • JSF 2.0 "forgot" about them • Alternative: PreRenderViewEvent <f:event type="preRenderView" listener="#{bean.preRender}"/> • Alternative: CODI @PreRenderView • Real view actions part of JSF 2.2 <f:metadata> <f:viewParam name="id" value="#{bean.id}"/> <f:viewAction action="#{bean.load}"/> </f:metadata>
  • 14.
    Post-Redirect-Get with JSF2 • Request /faces/myPage.xhtml?id=1 <h:form> <h:commandButton action="#{myBean.save}" value="Save"/> <h:commandButton value="Cancel" immediate="true" action="myPage?faces-redirect=true&amp; faces-include-view-params=true"/> </h:form> @Named @RequestScoped public class MyBean { public String save() { return "myPage?faces-redirect=true" + "&faces-include-view-params=true"; } }
  • 15.
    Demonstration • GET requestswith h:link and h:button • View Parameters • Post-Redirect-Get with JSF Beispiel: https://github.com/jsflive/jsf-get02
  • 16.
    RESTful URLs http://myshop.at/node.html?mode=list&cat=1234 http://myshop.at/products/books
  • 17.
    Why RESTful URLs? •Readability • Search Engine Optimization (SEO) • Confidence • Looks prettier
  • 18.
    RESTful URLs forJSF • PrettyFaces: RESTful URLS for JSF • By OCPsoft, Open Source • Features: • URL Rewriting • Enhanced navigation • Page actions • Seamless integration into JSF • Easy configuration
  • 19.
    PrettyFaces: Example 1(1) • Remove "JSF parts" of URL http://myshop.at/faces/account.xhtml http://myshop.at/account
  • 20.
    PrettyFaces: Example 1(2) • Configuration in pretty-config.xml <url-mapping id="account"> <pattern value="/account"/> <view-id value="/faces/account.xhtml"/> </url-mapping> • Annotation based configuration @Named @RequestScoped @URLMapping(id="account", pattern="/account", viewId="/faces/account.xhtml") public class AccountPage {}
  • 21.
    PrettyFaces: Example 2(1) • Map part of URL to parameter http://myshop.at/faces/products/details.xhtml?id=123 http://myshop.at/product/123
  • 22.
    PrettyFaces: Example 2(2) • Configuration in pretty-config.xml <url-mapping id="productDetails"> <pattern value="/product/#{id}"/> <view-id value="/faces/products/details.xhtml"/> </url-mapping> • Path parameter used in view parameter <f:metadata> <f:viewParam name="id" value="#{bean.id}"/> </f:metadata> <f:event type="preRenderView" listener="#{bean.preRender}"/>
  • 23.
  • 24.
    Conclusion • Lightweight Architecturewith Java EE 6 • JSF 2 simplifies GET support • PrettyFaces • Necessary for the intranet?
  • 25.
    Curious? • Kurz, Marinschek,Müllan: JavaServer Faces 2.0, dpunkt.Verlag • IRIAN JSF@Work Online-Tutorial http://jsfatwork.irian.at • JSFlive Weblog http://jsflive.wordpress.com