Tutorial: JSF 2 and HTML5 Server Sent Events

JSF co-spec lead Roger Kitain introduces us to composite components, combining JSF 2.0 with HTML5 Server Sent Events to form a powerful mix

The world of HTML5 offers many
features to facilitate the creation of exciting and dynamic web
sites. There are web communication specifications under the HTML5
“umbrella” that define a standard way to perform real-time
communication between browser clients and servers. One such
specification is the Server Sent Events specification. In
this article, we will explore how we can incorporate HTML5 Server
Sent Events into a JavaServer Faces (JSF) User Interface using some
of the new component features available since JSF 2.0.

HTML5 Server
Sent Events (SSE) is a W3C specification that defines a standard
API for opening an HTTP connection for receiving push notifications
(data) from the server. Operationally, it works the same as
Comet. However, Comet attempts to facilitate
“server push” over the existing HTTP request/response protocol
through various hacks such as appending scripts to iframes. The SSE
specification introduces a newEventSourceHTML element
that can be used with JavaScript to establish a connection to a
server end point. The client also registers event callback
JavaScript functions for handing “pushed” data from the server.
Let’s look at a client example:

This example shows a simple page
that will establish a connection to a server endpoint when the page
is loaded. On line 4, we create a new EventSource object, feeding
it the URL of a server endpoint. The server
endpoint could be a PHP script, NodeJS implementation, or even a
Java Servet. When a new EventSource instance is created, an initial
GET request to the server endpoint is done to establish the initial
connection. On line 5, we register a message callback that
will populate the events div with the event data. We could
have also registered a message handler on the EventSource instance
this way:

source.addEventListener('message', 'msgCallback', false);

As data is
pushed from the server, this callback will update the div area in
the page. It is also possible to handle multiple event types
from the server:

The event data for these events would be pushed over the same EventSource connection. It should be mentioned that SSE (namely the EventSource API) is not yet available in all browsers. Google Chrome is one such browser that has SSE support.

Server Requirements

The SSE
specification specifies requirements for the server response. The
specification states that the response content type must betext/event-stream. To send a single
line of data (Hello World!):

data: Hello World!nn

To send multiple lines of data:

data: This is the first linen
data: This is the second linenn

Here, a single string of data
concatenated with the newline character will be sent to the client
side event handler function. It is also possible to send the
response as JSON data:

data: {n
data: "msg":"hello world",n
data: "id:"12345n
data: }nn

In all cases, notice that two
successive newline characters end the response.

The User Interface

We’ll look at a simple “Stock View”
application that will cause the streaming of three event types to
the JSF user interface. This user interface
consists of three areas of information. The first area is the
“time” bar. The second area is the stock quote area that consists
of an input field to enter stock quotes, buttons to retrieve stock
quote information and reset (clear) the input area, and a table
that displays the stock quote information “real-time” as it is
updated on the server. The quote numbers are randomly generated on
the server, but real quotes could be retrieved by tying into a
quote service. The third area consists of a link to retrieve RSS
news feeds for the stocks, and a scrollable area that displays the
news feed. The news feed is also pushed from the server
“real-time”. Corresponding to these three areas are three SSE event
types:time, tickerandrss.When the user interface is first displayed, the clock will
tick real time. You enter space delimited stock symbols, press
theGet Quotesbutton and a
table is dynamically displayed with streaming quotes. Pressing
theGet Stock Newslink causes news feeds to stream from the
server.

The User Interface Markup

JSF 2.0 introduced three big
features that make it easier to develop dynamic user
interfaces.

Facelets becomes the primary view technology

Composite components make it easier to develop complex
components

Ajax support

Let’s see how
these three features are used in this user interface.
Listing 2 is the markup for the main user interface.

This user
interface uses four composite components. We’ll look at
these in more detail later on, but I summarize them here:

sse: Server Sent Events component
used to establish a connection to a server end point.

clock: Clock component displays the
ticking time bar

stock: Stock component that
produces the input field for entering stock symbols, the two
buttons, and a placeholder for the dynamic table that will display
stock ticker information.

rss: Component that produces the
linkGet Stock Newsand a
placeholder for the dynamic scrollable area that will display stock
news. This component is actually contained in the implementation of
the stock component which is why you don’t see it in this
view.

The first thing you’ll notice is
that on line 1 we’re using an HTML5 document type declaration. That
makes this document an HTML5 polyglot document because it has an
HTML5 document type /namespace and well-formed XHTML syntax – which
works great for JSF views. This would allow us to use other HTML5
features as well. Let’s take a look at the other relevant sections
of this view:

Lines 3
– 7: Here we declare the namespaces used in the user
interface. Lines 3 and 4 are just the standard JSF namespaces. Line
5 is the Facelets namespace. Line 6 declares the namespace that
we’ll use for our SSE component. Line 7 declares the namespace that
will be used for theclock, stockandrsscomponents.

Line 25: This is the usage of
the SSE component. This component uses two attributes:

url: The URL of the server endpoint that we are
connecting to

events: Specifiesevent
type : event handlerpairings. Theevent handleris the name of the
JavaScript function that will handle the associatedevent typedata coming from the
server.

Line 28: This is the usage
of theclockcomponent.Line
31: This is the usage of thestockcomponent.

It’s easy for a page author to use
well defined components in a view. Now let’s see how these
components are defined.

The Composite Components

Recall that JSF composite
components consist of two areas:

interface section

implementation section

Theinterfacesection is where you define
the usage contract for the component. It is where you define the
attributes that a page author would use with your component.
Theimplementationsection is
the code that produces the component. It may consist of HTML
markup, JavaScript and/or other JSF components. Let’s take a look
at the composite components that are used in this
application.

The SSE Composite Component

The Server Sent Events (SSE)
composite component is used to establish a connection to a server
endpoint. As mentioned earlier, this component
has two attributes. Let’s see how this component is
implemented.

Lines 4
– 7: This is just our namespace declarations. Line 7 is
declaring acompositenamespace
that will be used to define the relevant sections of our composite
component.

Lines 16
– 19: This is where we define theinterfaceor usage contract for our
composite component. On line 17 we define a requiredurlattribute whose value will be the
server endpoint. On line 18 we define theeventsattribute whose value will containevent type : event handler namemappings as shown earlier.

Lines 21
– 26: This is the implementation of the composite
component. JavaScript and JSF work together nicely to create
dynamic components. On line 22, we are loading a small JavaScript
library that contains functions for performing SSE operations for
JSF. Notice that we’re using a JSF component<h:outputScript>to specify the
target location of the JavaScript file. On line 24 we are using a
function from the JSF SSE JavaScript library to establish a
connection to the server endpoint using theurlandeventsattribute values.

So, the idea is that you can drop
one of these components in your JSF view to connect to a server
endpoint. Let’s take a look at the JavaScript library that contains
the functions for performing SSE actions.

Line
21: A private function that creates anEventSourceinstance to connect to the
server endpoint specified by the providedurl.

Line
45: The publicconnectfunction that is used in the SSE composite component in
Error: Reference source not found. This function calls through to
the private functiongetEventSourceand registers the application callback functions using a
publicaddOnEventfunction (line
99).

Line
74: A public utility function for registering an error
processing callback function. With SSE you can register a function
with theerrorevent
type.

Line 99: A public
utility function for registering callback functions for processing
event types.

Lines 9 – 11 :
Notice this component has no attributes – which is perfectly fine.
If we wanted to make this clock component fancier we could, for
example, define an attribute to indicate that our clock could
display in analog or digital mode.

Lines 13
– 18: The implementation of our component. On line 14, we
are using the Expression Language (EL) to invoke a method on a
managed bean to start the clock ticking. The managed bean could
just utilize ajava.util.Timermethod to compose and send the current date/time string
back to the client. Line 15 is a placeholder for where we will
display thetimeevent data from
the server. On Line 16, we load a JavaScript file that contains
application callback functions that will process the event data
returned from the server. Let’s take a look at the relevant section
of code from this application JavaScript file for this clock
component.

Line 18: The input
text field that will store the entered stock symbol data to a
managed bean.

Lines 19
– 21: The button that, when activated, will fire a request
over Ajax to invoke a methodgetStockInfoon a managed bean. This method could utilize
ajava.util.Timermethod to
reach out to a stock quote service periodically, and send the event
data back to the client.

Lines 29 – 36:
This is the placeholder area for our dynamic table to display the
stock data from the server.

Line
40: This component uses thersscomposite component (more about that
next).

TherssHandlercallback function writes the
rss event data into the div that was created in Error: Reference
source not found.

Server Implementation
Considerations

In the browser that has SSE
support. section, we mentioned some of the requirements for sending
SSE event data to the client. Server implementations need to
maintain an open connection to stream event data to the client. For
Java implementations, a Servlet utilizing the Servlet 3.0
Asynchronous API is one choice. For other implementations, NodeJS
or PHP could be used as well. Server implementation details are not
mentioned, since the main focus of this article is the JSF user
interface and components.

Conclusion

This article has been all about
creating JSF composite components that make up the user interface
for a stock quote application that uses HTML5 Server Sent Events.
JSF 2 introduced the world to composite components, and together
with JavaScript, provides a component author with a multitude of
options for creating dynamic components. HTML5 Server Sent Events
are the “second class citizen” to HTML5 WebSockets, but it does
offer an HTTP solution to event streaming without switching to
another protocol.

Roger Kitain is a Principal Software Engineer at Oracle where he has spent most of his time in the web technology space since 1997. Roger has been involved with the JavaServer Faces technology since its inception, and has co-led the JavaServer Faces Specification since JSF 1.2. He has presented at many conferences including JAX, JSF Summit, JavaOne, Dexoxx, Jazoon, Ajax Experience, Ajax World.