Work with Legacy Web Applications, Part II - JSP

From Documentation
DocumentationSmall Talks2006JulyWork with Legacy Web Applications, Part II - JSP
Work with Legacy Web Applications, Part II - JSP

Author
Tom M. Yeh, Chief Architect, Potix Corporation
Date
July 11, 2006
Version
Applicable to ZK 2.1.1 and later.


The Purpose

This is the second article in a series of small talks to illustrate how to use ZK with 'legacy' Web applications. In this article, we talked about how to use ZK in JSP pages.


Preface

ZK is a complete framework, and ZK applications don't depend on HTML forms, servlets or JSP. The recommended way is to listen events and process it as required. For example, you might listen to the onOK event to process what user has entered (instead of writing a servlet to process parameters). Then, you can either redraw a portion of page or redirect to a new page. It is more intuitive and powerful.

However, ZK is designed to co-exist with current technologies. After all, it is not practical and wasteful to rewrite the whole Web application just to enable the rich experiences.

Depending on the degree of modifications, there are several ways to adapt ZK into existent Web application. In the previous article we talked about how to keep servlets intact, yet rewrite the user interface. In this article we illustrate how to use ZK in JSP pages. In other words, we don't have to rewrite the whole JSP page with a ZUML page. Rather, we can add ZK components to existent JSP pages.

Example: User Profile Management

Assume we want to enrich the application that manages user profiles.

The use of JSP is quite dynamical. For the sake of illustration, we assume:

  • A class called Profile, which represents the user profile.
  • A JSP tag called load, which loads a Profile object from a database.


Here is the fragment before we adapt ZK.

<%-- JSP --%>
<db:load oid="${param.userOid}" var="profile"/>
  <%-- Assume <db:load> loads a Profile object from database and stores
  it in the request scope (so we can access it back with ${requestScope.profile})
  --%>
<form action="/updateProfile">
<table>
  <tr>
    <td>Firt Name</td>
    <td><input type="text" name="firstName" value="${requestScope.profile.firstName}"/></td>
  </tr>
  <tr>
    <td>Last Name</td>
    <td><input type="text" name="lastName" value="${requestScope.profile.lastName}"/></td>
  </tr>
  <tr>
    <td>Birthday</td>
    <td><input type="text" name="birthday" value="${requestScope.profile.birthday}"/></td>
  </tr>
  <tr>
    <td>Title</td>
    <td><input type="text" name="title" value="${requestScope.profile.title}"/></td>
  </tr>
  <tr>
    <td>Role</td>
    <td>
<select name="role"
  <option value="1"
    <c:if test="${requestScope.profile.role=='1'}">selected="selected"<c:if>>Determine need</option>
  <option value="2"
    <c:if test="${requestScope.profile.role=='2'}">selected="selected"<c:if>>Evaluate products/sesrvices</option>
  <option value="3"
    <c:if test="${requestScope.profile.role=='3'}">selected="selected"<c:if>>Recommend products/sesrvices</option>
  <option value="4"
    <c:if test="${requestScope.profile.role=='4'}">selected="selected"<c:if>>Implement products/sesrvices</option>
  <option value="5
    <c:if test="${requestScope.profile.role=='5'}">selected="selected"<c:if>">Techinical decision maker</option>
  <option value="6"
    <c:if test="${requestScope.profile.role=='6'}">selected="selected"<c:if>>Financial decision maker</option>
</select>
    </td>
  </tr>
  <tr>
  	<td colspan="2">
  	  <input type="submit" value="Update"/>
  	  <input type="reset"/>
  	</td>
  </tr>
</table>
</form>


And, the snapshot is as follows.

Profile-lega.gif

ZK the JSP Pages

JSP is a template technology to generate, theoretically, any content. In this example, it generates HTML tags. Thus, the concept to use ZK components in a JSP page is two-folds:

1. Generates the output in ZUML syntax.

2. Declares the ZK filter in WEB-INF/web.xml to post-process the output of a ZK page.

Generates the Output in ZUML Syntax

A XHTML page is a valid ZUML page. Thus, the first and only step to use ZK in a JSP page is to make sure that the output of the JSP page is XHTML. If you are not familiar with XHTML, you might take a look at XHTML at WIKIPEDIA.

In this example, the output is already XHTML, so nothing needs to adjust


Declares the ZK Filter

Assume you want ZK to post-process all JSP pages, and then you can add the following declarations to WEB-INF/web.xml.

<filter>
  <filter-name>zkFilter</filter-name>
  <filter-class>org.zkoss.zk.ui.http.DHtmlLayoutFilter</filter-class>
  <init-param>
	<param-name>extension</param-name>
	<param-value>html</param-value> <!-- Use XHTML components as default. -->
  </init-param>
</filter>
<filter-mapping>
  <filter-name>zkFilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>

Of course, if you just want ZK to process certain pages, just specify the proper url-pattern. Also, if you don't want ZK to process the output of included JSP pages, just remove <dispatcher>INCLUDE</dispatcher> from <filter-mapping>. Consult the Java Servlet Specification for details.


What Happens?

After correctly making the output to XHTML and mapping the ZK filter, you shall see the same result before using ZK.


Adding the Rich Content

Depending on your requirements, you can then add the rich content with ZK components, and dynamically change the content by listening to proper ZK events.

Let us say we want to replace the input with datebox and combobox, and then you can replace it with the following.

<%-- JSP --%>
<db:load oid="${param.userOid}" var="profile"/>
  <%-- Assume <db:load> loads a Profile object from database and stores
  it in the request scope (so we can access it back with ${requestScope.profile})
  --%>
<form action="/updateProfile" xmlns:x="http://www.zkoss.org/2005/zul">
<table>
  <tr>
	<td>Firt Name</td>
	<td><input type="text" name="firstName" value="${requestScope.profile.firstName}"/></td>
  </tr>
  <tr>
	<td>Last Name</td>
	<td><input type="text" name="lastName" value="${requestScope.profile.lastName}"/></td>
  </tr>
  <tr>
	<td>Birthday</td>
	<td><x:datebox name="birthday" value="${requestScope.profile.birthday}"/></td>
  </tr>
  <tr>
	<td>Title</td>
	<td><x:combobox name="title" value="${requestScope.profile.title}"/></td>
  </tr>
  <tr>
	<td>Role</td>
	<td>
<x:listbox name="role">
  <x:listitem value="1"
	selected="${requestScope.profile.role=='1'}" label="Determine need"/>
  <x:listitem value="2"
	selected="${requestScope.profile.role=='2'}" label="Evaluate products/sesrvices"/>
  <x:listitem value="3"
	selected="${requestScope.profile.role=='3'}" label="Recommend products/sesrvices"/>
  <x:listitem value="4"
	selected="${requestScope.profile.role=='4'}" label="Implement products/sesrvices"/>
  <x:listitem value="5"
	selected="${requestScope.profile.role=='5'}" label="Techinical decision maker"/>
  <x:listitem value="6"
	selected="${requestScope.profile.role=='6'}" label="Financial decision maker"/>
</x:listbox>
	</td>
  </tr>
  <tr>
	<td colspan="2">
	  <input type="submit" value="Update"/>
	  <input type="reset"/>
	</td>
  </tr>
</table>
</form>


Manipulate Content Dynamically

No matter XUL or XHTML components, you can add event listeners to them as you did with regular ZUML pages. Then, manipulate the components in the proper event listeners.

As depicted below, the role of the ZK filter is the same as that of the ZK loader. It creates components based on the output of a JSP page, and then these components communicate with the browser via the ZK Update Engine. In other words, JSP pages are just a way to generate ZUML pages dynamically. You don't lose any ZK power when using the ZK filter.

How-it-works.gif


For example, you can add a button to add a specialty to a user profile as follows.

<html xmlns:zk="http://www.zkoss.org/2005/zk">
...
<input type="button" value="Add Specialty" zk:onClick="addSpecialty()"/>
<zscript>
void addSpecialt() {
	//does whatever you want
}
</zscript>


Debugging

A common error is that the output of a JSP page is not XHTML. To debug it, you can turn off the filter first and view the result at the browser. Then, save the source as a ZHTML file and then visit the ZHTML file directly. Or, copy and paste the content to zkdemo to see whether it is correctly rendered.


Summary

There are two steps to use ZK with JSP pages:

1. Generates the output (of a JSP page) in ZUML syntax, or at least XHTML.

2. Declares the ZK filter in WEB-INF/web.xml to post-process the output of a ZK page.




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.