Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Martin Marinschek on Java Server Faces 2.0

Martin Marinschek on Java Server Faces 2.0

More Decks by Enterprise Java User Group Austria

Other Decks in Technology

Transcript

  1. 08.12.08 Yours sincerely, Martin Marinschek • wrote the first productive

    JSF application (on Apache MyFaces, then version 0.3) • CEO of IRIAN, a consultant house specialized on Java, web-apps and JSF (based in Vienna) • member of the JSF 2.0, Webbeans, JSF Metadata, JSF Portletbridge expert groups • Committer of Apache MyFaces, Facelets, Apache member • Consultant @Credit Suisse • rebuilding the 3rd largest app-suite of CS with (cs)JSF • writes books on web-frameworks (e.g. JSF, GWT, Rails) • frequently speaks on JSF and web-application development
  2. 08.12.08 The rules • Note down these 9 terms •

    When you have found all of them • after the main content start slide (Servlet 3.0) • On my slides – not surfing the web .. • You stand up and scream: „Buzzword Bingo“ • If nobody stands up until I show the next slide, my girlfriend will get everything • The winner takes it all:
  3. 08.12.08 Martin Marinschek 9 Backwards compatibility • does your app

    partially extend from Facelets-classes? • yes – you can keep the old Facelets-jars and configuration • set javax.faces. DISABLE_FACELET_JSF_VIEWHANDLER • no – you don't need Facelets old anymore
  4. 08.12.08 Martin Marinschek 10 New • Always build before restore!

    • after restore view, you always have access to the full component tree • Facelets Composite comp = always a UIComponent instance • what if you don't want this? • currently under discussion • transparent components • (Optional) Metadata  you can use Action-methods directly! Yay!
  5. 08.12.08 Martin Marinschek 11 Component implementation <composite:implementation > <ui:decorate template="fooTemplate.xhtml">

    <ui:define name="header"> <p>This is the login panel header</p> </ui:define> <ui:define name="body"> <p> <h:inputText id="username" /> </p>
  6. 08.12.08 Martin Marinschek 12 Component Implementation <p> <h:commandButton id="loginEvent" value="Login"

    action="#{compositeComponent.elAttrs.model.loginAction}" > </h:commandButton> <h:commandButton id="cancelEvent" value="Cancel" action="cancel"> </h:commandButton> </p> </ui:define> <ui:define name="footer"> <p>This is the login panel footer</p> </ui:define> </ui:decorate> </composite:implementation>
  7. 08.12.08 Martin Marinschek 13 Optional Metadata <composite:interface name="foo" displayName="Very Simple

    Login Panel" preferred="true" expert="false" shortDescription="An illustration of the composite component feature"> <composite:attribute name="model" required="true"> <composite:attribute name="loginAction" required="true" method-signature="java.lang.Object action()"/ > </composite:attribute> <composite:editableValueHolder name="username" /> <composite:actionSource name="loginEvent" /> <composite:actionSource name="cancelEvent" /> <composite:actionSource name="allEvents" targets="loginEvent,cancelEvent" /> </composite:interface>
  8. 08.12.08 Martin Marinschek 15 Use it (in the standard...) <h:commandButton

    id="submit" value="submit" partialSubmit="true" partialGroups="grp1, grp2"/> You embed a child element for more configuration options: <h:commandButton> <f:ajax execute="grp1, grp2" render="grp1, grp2"/> </h:commandButton>
  9. 08.12.08 Martin Marinschek 16 f:ajax • events: valueChange or action

    • execute: group of ids • render: group of ids • onevent: javascript to be executed • onerror: javascript to be executed on error • disabled: should this behavior execute or not? • listener: server-side method expression to be called
  10. 08.12.08 Martin Marinschek 17 You can also wrap: <f:ajax execute="grp1,

    grp2" render="grp1, grp2"> <h:commandButton/> <h:inputText/> </f:ajax>
  11. 08.12.08 Martin Marinschek 18 For more flex, you can do:

    var viewState = javax.faces.Ajax.viewState(form); <h:commandButton id="submit" value="submit" onclick="javax.faces.ajax.ajaxRequest(this , event, {execute:'submit',render:'outtext'}); return false;" /> last option: associative array, keys: "execute", "render", values – component-ids to be executed or rendered javax.faces.Ajax.ajaxResponse(request); - called when everything is done to update DOM
  12. 08.12.08 Martin Marinschek 19 Say you want it (from comp):

    @ResourceDependency (name="jsf.js", library="javax.faces", target="head") public class MyComponent extends UIOutput {...}
  13. 08.12.08 Martin Marinschek 20 Partial Lifecycle • execute, render tie

    into the lifecycle • only these portions will be executed • processDecodes, ...Validators, ...Updates, render-methods need to take the following information into account: FacesContext.isAjaxRequest() FacesContext.getExecutePhaseClien tIds();
  14. 08.12.08 Martin Marinschek 21 Request-Queue • requests will be queued

    • only one at a time • if one fails, error message might be shown, then next one is executed
  15. 08.12.08 Martin Marinschek 22 For AJAX: new feat. Behaviors •

    An attached object like converter/validator • Behaviors allow to send scripts to the client • Also take part in decoding String getScript(BehaviorContext c); void decode(fc, UIComponent co); String getRendererType(); void broadcast(BehaviorEvent ev); Set<String> getHints();
  16. 08.12.08 Martin Marinschek 24 Annotations • @FacesComponent • @FacesConverter •

    @ManagedBean • more than one name/scope: @ManagedBeans • @ManagedProperty • @FacesRenderer • @FacesRenderKit • @FacesValidator
  17. 08.12.08 Martin Marinschek 26 State-saving, Take II • first state-saving

    approach rather clumsy • save everything from everywhere
  18. 08.12.08 Martin Marinschek 27 New Approach (I) • build the

    components from the template in the beginning • tell the components when they have been built  Initial or eden-state • components remember only stuff on top of this • internal storage: maps (with a property-key) • my estimate: less then 1/10 of current application state
  19. 08.12.08 Martin Marinschek 28 New Approach (II) • no restoreState/saveState

    anymore, if no special overrides • whatever is set to the map after Eden-State callback is automatically restored/saved • restore/save the state per component - independent • not by passing in a bloated object[ ] to the root  Tree Visitor
  20. 08.12.08 Martin Marinschek 29 Tree-Visitor • UIComponent.getFacetsAndChildren() is not enough

    • does not work with structured components (flyweight-pattern) • Therefore, there is now a visitor: – UIComponent.visitTree(VisitContext ctx, VisitCallback contextCallback);
  21. 08.12.08 Martin Marinschek 30 Plus: a lot easier to create

    own components • no restoreState / saveState need to be implemented • prepare an enum which keys the attributes enum Keys { rendered, collapsed, disabled }
  22. 08.12.08 Martin Marinschek 31 Easier comps (II) • Getter and

    setter call through to the map: boolean isRendered() { return (Boolean) getStateMap(). get(Keys.rendered, true); } void setRendered(boolean rendered) { getStateMap().put(Keys.rendered, rendered); }
  23. 08.12.08 Martin Marinschek 33 Annotate beans: public class Customer {

    @NotNull @Size(min=2, max=20) private String telephoneNumber; }
  24. 08.12.08 Martin Marinschek 34 Automatic validators • For these annotations

    • Automatic validators are queued • JSF components bound to these attributes
  25. 08.12.08 Martin Marinschek 36 Queue exceptions • At any point

    of time during the life-cycle, throw an exception or call: Application.publishEvent( ExceptionEvent.class, eventContext);
  26. 08.12.08 Martin Marinschek 37 Handle exceptions • Exceptions will then

    be handled: • at the end of each lifecycle-phase • Exception-handler class: • void handle() throws FacesException • the exception-handler can be decorated • register exception handler factory in faces- config
  27. 08.12.08 Martin Marinschek 39 Voila: the resource handler • Get

    the ResourceHandler: application.getResourceHandler() • Is this a resource-request? resourceHandler.isResourceRequest()
  28. 08.12.08 Martin Marinschek 40 Resource-Identifier A resource identifier consists of

    (square brackets means optional): [localePrefix/][libraryName/] [libraryVersion/]resourceName[/resourceVersion] • This will be evaluated relative to either: • web-application-root/resources (means call to externalContext.getResource()) • classpath:/META-INF/resources (means call to getContextClassLoader().getResource())
  29. 08.12.08 Martin Marinschek 41 Samples • duke.gif • corporate/duke.gif •

    corporate/2_3/duke.gif • basic/2_3/script.js/1_3_4.js • de/header.css • de_AT/footer.css/1_4_2.css • zh/extraFancy/menu-bar.css/2_4.css • ja/mild/0_1/ajaxTransaction.js • de_ch/grassy/1_0/bg.png/1_0.png
  30. 08.12.08 Martin Marinschek 42 Create a resource URL - Java

    • Resource resource = resourceHandler.createResource(Strin g resourceName, String libraryName) • String path = resource.getRequestPath(); • versions are automatically resolved (the last version is taken)!
  31. 08.12.08 Martin Marinschek 43 Create a resource URL - Template

    • <h:graphicImage value="#{resource[‘images:Planets.gi f’]}"/> • certain tags will have new attributes: <h:graphicImage name="Planets.gif" library="images"/> • new tags (supporting attr target, see later): <h:outputScript /> <h:outputStylesheet/>
  32. 08.12.08 Martin Marinschek 44 Create a resource URL - Annotation

    • @ResourceDependency (ies) • on Renderer, Component, Converter, Validator • attributes name, library, target
  33. 08.12.08 Martin Marinschek 45 Relocatable resources • attribute target allows

    to specify a relocation • target="head" relocates to head • for this: – h:head / h:body • special renderers for head and body • resource-renderers (for script, stylesheet, etc. references)
  34. 08.12.08 Martin Marinschek 46 E.g.: Script-Renderer @ListenerFor(facesEventClass=AfterAdd ToParentEvent.class, sourceClass=UIOutput.class) public

    class ScriptRenderer extends Renderer implements ComponentSystemEventListener  puts UIOutput with this renderer-class to <f:facet name="head"> under UIViewRoot
  35. 08.12.08 Martin Marinschek 48 System Events • Two subtypes: •

    Application System Events • Component System Events • Can be queued on: • Application.subscribeToEvent(); • Component.subscribeToEvent(); • or with annotations: • @ListenerFor and @ListenersFor • Components, Renderers, Validators, Converters can use this
  36. 08.12.08 Martin Marinschek 49 Types of events AfterAddToViewEvent BeforeRenderEvent ViewMapCreatedEvent

    ViewMapDestroyedEvent ApplicationPostConstructEvent ApplicationPreDestroyEvent
  37. 08.12.08 Martin Marinschek 50 Better GET/Bookmarking support • New component:

    <h:outcomeTarget value="Link text" outcome="nextPage" /> • Evaluates the navigation-system immediately and returns the following page • To still have some dynamics – nest an <if>EL-expression</if> – inside navigation-case • GET-URL is rendered
  38. 08.12.08 Martin Marinschek 52 How does the target get params?

    • either nest params: – <f:param/> • or set optional attribute: includeViewParams to true (default false)
  39. 08.12.08 Martin Marinschek 53 Target page: • Target-page has: <f:metadata>

    <f:pageParam value="param1" target="#{bean.param1}"/> </f:metadata> • embedded in the <f:view/> tag • if you use templating, you will need to put a ui:insert/ui:define combination at this location
  40. 08.12.08 Martin Marinschek 54 Not yet: integration Servlets 3.0 •

    modularization: faces servlet might be auto- registered by default • asynchronous servlets: • before invoke application • prevention of thread starvation • and support of asynchronous backends • faces servlet: • startAsync(): store FacesContext in request- map • restore it when the request is continued
  41. 08.12.08 Martin Marinschek 56 Current UIComponent • public static UIComponent

    getCurrentComponent(fc) • public static UIComponent getCurrentCompositeComponent(fc) • stored in FacesContext.getAttributes() • under key: javax.faces.component.CURRENT_COMPON ENT
  42. 08.12.08 Martin Marinschek 57 FacesContext • currentPhaseId(); - provide the

    current phase-id • enableResponseWriting(); - lift/set down the pen for rendering • getAttributes(); - a map of generic attributes • isPostback(); - is the request a post-back? • getPartialViewContext() - AJAX-related info
  43. 08.12.08 Martin Marinschek 58 View-Map • Off the view-root, there

    is a new view-map • provides a view-scope to the application • data stored in this scope will be available as long as a view is available • you can put a managed-bean in scope: view
  44. 08.12.08 Martin Marinschek 59 NavigationHandler • new interface: ConfigurableNavigationHandler •

    NavigationHandler will implement this • new methods: – getNavigationCase(fc, String fromAction, fromOutcome); – Map<String, Set<NavigationCase>> getNavigationCases();
  45. 08.12.08 Martin Marinschek 61 Facets • Facets can now have

    more than one child- element • no wrapper element necessary anymore