Skip to content

Latest commit

 

History

History
61 lines (43 loc) · 4.42 KB

File metadata and controls

61 lines (43 loc) · 4.42 KB

JSF in brief

This document gives a rough and incomplete overview of JavaServer Faces (JSF, 2.2, JSR 344).

Note
The reader supposedly has basic knowledge of Servlets, CDI, XML (including namespaces) and Java EE Application servers.

Motivation

One of the goals of JSF is to provide HTML pages to your clients, built on your server. Let’s first see why you can’t do this using simple Java EE servlet technology. Following a simple servlet development, here is what happens:

  1. the client (say, the web browser of a user) requests a page from your servlet (say, sends a GET request to http://your-server/some-web-page);

  2. the container (sitting on the Java EE application server) directs the request to your servlet;

  3. your servlet processes the request, and returns an answer to the client;

  4. this answer gets (for example) displayed in the user’s browser.

This works well if you need to return, for example, a simple text to the client. But what if your client expects a nice HTML page in return? You might use the writer in your servlet to write tags manually, but this would be extremely cumbersome and error-prone. One of the benefits of JSF is that it provides a clean solution for this use case.

Design overview

In JSF, you write a page using the “Facelets” technology. (You can view this as a declarative language similar to HTML.) This page gets interpreted by the container when it detects a request directed to it. The (very high-level) process is as follows.

  • The container builds an intermediate tree from this page: a tree of JSF components.

  • The container calls your code as necessary for validating the input from the user (if any) or obtaining information needed for the response. This possibly modifies the tree of components (e.g. by changing the text associated to some components).

  • Finally, the container renders the tree, which builds an HTML representation of it, and send the resulting data as an HTTP answer to the client.

Example

An example of a Facelet page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Greetings page</title>
</head>
<body>
	<p>
		Hi, <h:outputText value="#{user.name}" />.
	</p>
</body>
</html>

Assume a client sends an HTTP GET request to your application server, and assume your server is configured for directing that request to this example Facelet page.

  • All unprefixed elements (e.g. html, head) and simple text will simply be passed through to the client.

  • The only special element here is the outputText element, that sits in the JSF namespace (thanks to the h prefix). The container builds a component of type HtmlOutputText representing this element. The container knows this by convention: the JSF specification lists JSF tags and their corresponding components.

  • This component gets added to the tree of components representing the Facelet page being processed. In this example, the tree is very simple as there is only one explicit JSF component in this page.

  • The container sets the value of the newly created HtmlOutputText component to (something like) "#{user.name}". Actually, this represents a “value expression” that will be evaluated by the container at some point in the JSF treatment cycle.

  • A managed bean (as understood from the CDI specification) must exist under the name user for the evaluation of the "#{user.name}" value expression to work. Assuming such a bean exists, the container will get the name property of the user bean and put it into the value of the HtmlOutputText component.

  • Finally, the container will render the page, that is, convert it into an equivalent html representation, and send it back to the client as the HTTP answer to its request. Components get rendered to html in different manners depending on their type. HtmlOutputText components simply render their value.

Supplementary details

Inversion of control JSF implements a (second level of) Inversion of Control (IoC) pattern, supplementary to the usual IoC happening when you build a classical servlet (see Servlets.adoc): you do not control the flow of the code, rather, the container calls your code at specified time points during the JSF treatment cycle.