ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

51
ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS Craig R. McClanahan Senior Staff Engineer Sun Microsystems, Inc.

description

 

Transcript of ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

Page 1: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTSCraig R. McClanahanSenior Staff EngineerSun Microsystems, Inc.

Page 2: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

2

Agenda• Background• Introduction to JavaServer Faces• Architectural Decisions• Examples:> Auto Complete Text Component> DynaFaces AJAX Zones

• Summary• Resources

Page 3: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

3

Background

Page 4: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

4

Background• Building AJAX based applications is easy ...> If you are a JavaScript guru> If you have memorized the entire DOM API> If you own and study books on DHTML, JavaScript, CSS,

AJAX, and useful hacks for each technology• Building AJAX based applications is hard ...> If you come from a mostly static HTML/CSS background> If you are comfortable with traditional web application

architectures built around an HTTP POST> If your primary use of JavaScript is cut-n-paste of cute

animations and other cool in-page behaviors

Page 5: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

5

Background• Can we make this process easier for mere mortals?• Classic computer science answer: encapsulation> Hide functionality behind simple building blocks> Provide a framework for assembling complicated things

out of simple things> Embed the encapsulations inside development tools that

can do some of the grunt work• In this talk, we will examine using JavaServer Faces

to encapsulate AJAX technologies> But first, we need to understand what JavaServer Faces

(JSF) is all about ...

Page 6: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

6

Introduction to JavaServer Faces

Page 7: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

7

The Classic Definition

“JavaServer Faces is a server side, user interface component framework for building Java technology based web applications.”

Page 8: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

8

Key Concepts• User Interface Components• Value and Method Binding• Managed Beans• Navigation• Request Processing Lifecycle

Page 9: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

9

User Interface Components• Contains the current state of a component:> Visual appearance characteristics> Bindings to model tier data and event handlers

• Implemented as a classic JavaBean:> Properties – state characteristics> Methods – encapsulated behavior exposed to apps> Events – respond to UI related events

• Composed into a component tree per logical view> Single “view root” component> Arbitrary levels of nesting for child components

Page 10: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

10

User Interface Components

Page 11: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

11

User Interface Components• Supporting APIs:> Converters – Convert between String and Object> Validators – Correctness checks on input> Renderers – Markup creation is separated from the

component itself– Allows components to be used for different markup languages– Renderers gathered into a “render kit”

• Component tree is typically visualized in some sort of template language:> Most commonly used – JavaServer Pages (JSP)> Other alternatives available as well

Page 12: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

12

Example Logon FormBasic User Interface Components<f:view> <h:form id=”logonForm”> <h:panelGrid columns=”2”> <h:outputLabel for=”username” value=”Username:”/> <h:inputText id=”username”/> <h:outputLabel for=”password” value=”Password:”/> <h:inputSecret id=”password”/> <h:outputText value=””/> <h:commandButton id=”logon” value=”Log On”/> </h:panelGrid> </h:form></f:view>

Page 13: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

13

Value and Method Binding• Application access to the component tree:> Programmatic API to look up components by ID> DOM-like navigation of the component tree> Option for binding direct references

• Component access to model tier data:> Value binding expressions:

– Example: #{customer.address.city}– Based on syntax of JavaScript object references

> Bidirectional access:– “Pull” data when rendering the view– “Push” data when processing the postback

Page 14: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

14

Value and Method Binding• Component access to server side event handlers:> Method binding expressions:

– Example: #{logonBean.logon}– Evaluated like value binding expressions to the last “.”– Last name treated as a method name to be called

• Let's decorate our example view with some binding expressions ...

Page 15: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

15

Example Logon FormWith Value and Method Binding Expressions<f:view> <h:form id=”logonForm”> <h:panelGrid columns=”2”> <h:outputLabel for=”username” value=”Username:”/> <h:inputText id=”username” value=”#{logonBean.username}”/> <h:outputLabel for=”password” value=”Password:”/> <h:inputSecret id=”password” value=”#{logonBean.password}”/> <h:outputText value=””/> <h:commandButton id=”logon” value=”Log On” action=”#{logonBean.logon}”/> </h:panelGrid> </h:form></f:view>

Page 16: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

16

Managed Beans• How do value and method binding expressions get

resolved?> First term (logonBean) treated as a variable name> JSF searches request scope, session scope, and

application scope for an attribute by this name– If found, that object is used– Otherwise, creates a new object based on configuration

> Remaining terms access properties (or methods)• Typical architectural pattern is a “backing bean” for

each JavaServer Faces view> Normally in request scope

Page 17: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

17

Example Logon FormManaged Bean Definition (in “faces-config.xml”)<faces-config> ... <managed-bean> <managed-bean-name>logonBean</managed-bean-name> <managed-bean-class> com.mycompany.mypackage.MyLogonBean </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> ... optional property configuration ... </managed-bean> ...</faces-config>

Page 18: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

18

Example Logon FormBacking Bean Java Source (Part 1)package com.mycompany.mypackage;public class MyLogonBean { // No required base class // The “username” property private String username; public String getUsername() { return this.username; } public void setUsername(String username) { this.username = username; } // The “password” property private String password; public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; }

Page 19: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

19

Example Logon FormBacking Bean Java Source (Part 2)

// Event handler to perform the logon // Called when “Log On” button is pressed public String logon() { Authenticator auth = ...; // Get business logic if (auth.authenticate(username,password)) { return “success”; // Input to navigation rule } ... add error message to be displayed ... return null; // “Please redisplay this view” }}

Page 20: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

20

Navigation• Standard navigation based on three inputs:> What view is being processed?> What action method was invoked?> What logical outcome was returned?

• Logical outcome of null is treated specially:> Please redisplay the current page

• Navigation rules defined in faces-config.xml along with managed beans definitions

Page 21: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

21

Example Logon FormNavigation Rule Definition (in “faces-config.xml”)<faces-config> ... <navigation-rule> <from-view-id>/logon.jsp</from-view-id> <navigation-case> <from-action>#{logonBean.logon}</from-action> <from-outcome>success</from-outcome> <to-view-id>/mainmenu.jsp</to-view-id> </navigation-case> </navigation-rule> ...</faces-config>

Page 22: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

22

Request Processing Lifecycle

Page 23: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

23

Request Processing Lifecycle• Two processing scenarios:> Initial request (or an HTTP GET)

– Restore View --> Render Response> Postback request (an HTTP POST)

– Entire lifecycle

• Special case for portlet (JSR-168) environments:> Postback goes to one portlet

– Restore View ... Invoke Application> All portlets are asked to render themselves

– Render Response

Page 24: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

24

Architectural Decisions

Page 25: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

25

Architectural Decisions• To AJAX or not to AJAX, that is the question ...• Render markup + code or just code• Manage client side interactions• Access static resources• Asynchronous callbacks – client side view• Asynchronous callbacks – server side view

Page 26: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

26

To AJAX Or Not To AJAX ...• First inclination when talking about AJAX and JSF:> Create AJAX-aware versions of every component

• When does this make sense?> Individual component needs remote access for state:

– Assumption: visualization depends on server state changes– Example: Progress Bar (for server side process)– Example: RSS News Headlines (that dynamically change)– Example: “Is this username already taken?” validation

> Individual component needs remote access for data:– Assumption: too much data to load with the initial page– Examples: Auto Complete Text Field, Table, Tree Control

Page 27: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

27

To AJAX Or Not To AJAX ...• When does this not make sense?> Primarily interested in partial page submit:

– Grab a subset of the input elements on this page, and ...– Submit them to update server side state ...– Without requiring a full page submit

> Primarily interested in partial page refresh:– Respond to a partial page submit by ...– Updating part of the current view ...– Without requiring a full page redisplay

• Frameworks exist to provide these facilities for any JavaServer Faces component> We will see an example later

Page 28: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

28

To AJAX Or Not To AJAX ...• Recommendations:> Design or use AJAX enabled components when

necessary> Use frameworks to manage partial page submit and

partial page refresh scenarios

Page 29: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

29

Render Markup+Code Or Just Code• First inclination when talking about AJAX and JSF:> Render all the markup and related JavaScript code for

each component individually> Note: Applies to non-AJAX components also

• When does this make sense?> Markup is very simple and/or highly use case specific> Corresponding JavaScript code is very simple> Note: Hybrid solution is also feasible:

– Generate custom markup per component– Reference JavaScript libraries for code common to all

occurrences of a particular component

Page 30: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

30

Render Markup+Code Or Just Code• When does that not make sense?> Markup is complex> Corresponding JavaScript code is complex> Using a JavaScript “widget” library for rendering

• Recommendations:> Use JavaScript “widget” libraries when feasible:

– JSF renders JS code to create and configure the widget> Factor per-component JavaScript into static resources:

– Leverage client side caching– Ensure that required resources are loaded transparently– Ensure that required resources are loaded once per page

Page 31: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

31

Manage Client Side Interactions• First inclination when talking about AJAX and JSF:> Create custom JavaScript APIs to interact with other

client side components> Note: Applies to non-AJAX components also

• When does this make sense?> Providing functionality above and beyond standard

JavaScript event handlers– Such as an asynchronous callback to update state

> Encapsulating complex interactions– Such as coordinated updates of multiple client side elements

Page 32: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

32

Manage Client Side Interactions• When does this not make sense?> When standard JavaScript event handlers are sufficient

– Leverage developer familiarity> When you want to support “unanticipated” interactions

– Document enough about internal architecture to allow this

• Recommendations:> Use standard client side interaction paradigms:

– JavaScript object per widget– Standard event handlers where feasible

> Consider event-driven or publish/subscribe paradigms> JSF Specific – be aware of component id generation

algorithms

Page 33: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

33

Access Static Resources• First inclination when talking about AJAX and JSF:> Embed all required JavaScript and stylesheets in the

generated markup of each component> Note: Applies to non-AJAX components also

• When does this make sense?> When the required JavaScript is very simple and/or use

case specific> When the required stylesheet information is very simple

and use case specific

Page 34: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

34

Access Static Resources• When does this not make sense?> JavaScript for a particular component can be factored

into a common library> CSS styles can be factored into common stylesheets that

can be overridden by the developer• Recommendations:> Factor JavaScript and CSS into static resources> Ensure that only one copy of each resource gets loaded

into a single page> Trigger runtime loading of static resources transparently

– Developer should not need to care that your component needs a particular script file or stylesheet

Page 35: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

35

Asynchronous Callbacks – Client• First inclination when talking about AJAX and JSF:> Hand code the XMLHttpRequest handling individually for

each component• When does this make sense?> Basically never :-)

• When does this not make sense?> Basically always :-)

Page 36: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

36

Asynchronous Callbacks – Client• Recommendations:> Encapsulate XMLHttpRequest handling into common

JavaScript functions– Per component, or ideally, per library

> Leverage existing JavaScript frameworks:– More elegant client side APIs– Hide browser dependencies

> Leverage facilities of the server side framework:– See next section ...

Page 37: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

37

Asynchronous Callbacks – Server• First inclination when talking about AJAX and JSF:> Write a custom servlet for each component's

asynchronous callback handler• When does this make sense?> In simple use cases> When the client side is not your JSF component library

• When does this not make sense?> Asynchronous callback needs to access and/or update

the JSF component tree for the current view> Need to manage data serialization and deserialization

– Affects client side also

Page 38: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

38

Asynchronous Callbacks – Server• Recommendations:> Leverage JSF server side framework capabilities:

– JSF component state for PPS/PPR use cases– Managed beans for simple IoC requirements

– Can integrate more complex frameworks for non-simple use cases– Method binding expresions to invoke server side logic

> Utilize libraries and frameworks for data transport:– Common formats: XML and JSON– Minimize requirements imposed on the server side developer

as well as the client side developer> Support non-JSF-component clients:

– Not every UI will be created with JSF, or even Java– Not every callback will be from a browser

Page 39: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

39

Examples

Page 40: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

40

Examples• Auto Complete Text Field Component• Dynamic Faces (DynaFaces) AJAX Zones

Page 41: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

41

Auto Complete Text Field

Page 42: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

42

Auto Complete Text Field• To AJAX Or Not To AJAX:> Provide embedded AJAX functionality

• Render Markup+Code Or Just Markup:> Hybrid: custom (simple) markup, shared JavaScript

• Client Side Interactions:> Component creates well-known DOM element ids> Standard JavaScript events plus two custom ones

• Access Static Resources> Shale Remoting library

Page 43: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

43

Auto Complete Text Field• Asynchronous Callbacks – Client Side:> Standard JavaScript object per component instance> Utilize DOJO Toolkit for asynchronous IO> Simple XML data format

• Asynchronous Callbacks – Server Side:> No need to access JSF component tree state> Component-provided managed bean for callback handler> Component invokes application-provided method (with

simple API) to provide data– Application developer does not need to know the gory details

Page 44: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

44

Demo

Page 45: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

45

Dynamic Faces (DynaFaces)• Extension framework for JavaServer Faces 1.1/1.2> Built on top of standard extension APIs

• Delivers solutions for several of our focus areas:> To AJAX Or Not To AJAX:

– AJAX Zones for partial page refresh scenarios– Works with non-AJAXified components

> Client Side Interactions:– Trigger asynchronous callbacks programmatically– Deferred transactions for post-callback event handling

> Server Side Interactions:– Fire server side event handlers– Manage client-server data formatting

Page 46: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

46

Demo

Page 47: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

47

Summary

Page 48: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

48

Summary• JavaServer Faces was originally targeted as a

traditional server-side-markup-generation component framework• JavaServer Faces can be leveraged in many ways

to build AJAX-based web applications• JavaServer Faces supports the use of AJAX

techniques on components not specifically designed for AJAX interactions

Page 49: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

49

Resources

Page 50: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

50

Resources• JavaServer Faces:> http://java.sun.com/javaee/javaserverfaces/

• Java BluePrints Catalog:> http://java.sun.com/reference/blueprints/

• AJAX Developer Resource Center:> http://developers.sun.com/ajax/

• Apache Shale Framework:> http://shale.apache.org/

• DOJO Toolkit:> http://dojotoolkit.org/

Page 51: ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTS

ENCAPSULATING AJAX FUNCTIONALITY IN JAVASERVER FACES COMPONENTSCraig R. [email protected]