Archive for Web Development

JSF/MyFaces f:selectItems and automatic converters

JSF converters provide a way for mapping complex Java types to the UI. A class converter is registered for a type and is then called every time an object of the given class is rendered to the UI (or posted from a form), unless another converter is specified. For example, registering the following converter in your faces-config.xml provides automatic conversion of Enum values (a similar converter is already included in JSF 1.2, but missing in 1.1):

<converter>
<converter-for-class>java.lang.Enum</converter-for-class>
<converter-class>com.dlicht.converter.EnumConverter</converter-class>
</converter>

With this, you can for example use Enums for selectItem values. What I did not fully realize and what cost me hours before I stepped through the MyFaces source is that the converter is determined through the input component’s value mapping type, not the value type of the selectItems themselves. Although this does make sense (because it’s the bean property that represents the the component value, and not the current selectItem, and the selectItem values of a select list don’t even have to be of the same type), it’s not entirely trivial. For example,

<h:selectOneListbox value=”#{myBean.enumProperty}”>
<f:selectItems value=”#{myBean.enumValues}”/>
</h:selectOneListbox>

works without an explicit converter, but

<h:selectOneListbox>
<f:selectItems value=”#{myBean.enumValues}”/>
</h:selectOneListbox>

does not.

Advertisements

Comments (1)

Ajax, JSF and JSON: JSON-RPC-Java

While ajax4jsf is a very nice Ajax framework for JSF, it’s sometimes too expensive to submit an entire form and re-render (parts of) the page just to update some data. For client-side components, like many of Dojo’s UI widgets, JSON is a simple and convenient way to represent data. It is especially useful for components that need to pull data from the server, such as a result table scrolling through thousands of rows. Instead of re-rendering the entire page, the required data is transferred via JSON and then the widget is re-rendered using JavaScript. JSON-RPC-Java provides a convenient wrapper for Java RPC (Remote Procedure Call) through JSON, i.e. both the server request and the response are encoded in JSON (instead of, say, XML).

In JSON-RPC-Java, remote procedure calls are routed through a single servlet. The server-side methods are implemented in POJOs and registered with the user session. Parameter types are determined with reflection and mapped to the corresponding JavaScript types. To get an impression of what this is about, consider this trivial (and somewhat useless) Java class implementing an uppercase service:

class MyObject {
public String toUppercase(String value) {
return value.toUpperCase(Locale.ENGLISH);
}
}

This code runs somewhere on your web server, giving you full access to any business data and methods necessary. A dynamic JavaScript proxy provided by JSON-RPC-Java allows you to call the remote procedure like a local function, e.g. to call MyObject#toUppercase(“sheep”) you would code in Javascript:

new JSONRpcClient("/jsonRpcServlet").MyObject.toUppercase("sheep")
-> "SHEEP"

In this case, the call is synchronous, i.e. the browser blocks until the response arrives. In most cases, this is not what you want for a responsive user interface. To make asynchronous calls, the first parameter to the remote procedure is a function reference. The JSON/RPC call will then proceed immediately, and the callback function will be executed when the server response arrives. For example:

function myCallback(result) { alert(result); };
new JSONRpcClient("/jsonRpcServlet").MyObject.toUppercase(
myCallback, "sheep")

Compared to using ajax4jsf, this is simple and efficient. However, there are two drawbacks: First, the remote procedure call likely returns raw data, not markup ready to be passed to the client. This is not an issue with Dojo widgets since they are pure client-side JavaScript components, but it prevents you from updating parts of the rendered page without writing Ajax-aware components (which is exactly what ajax4jsf allows you to do).

Second, and not so obvious, the servlet completely circumvents the JSF environment. That means no lifecycle, no phase events, and no JSF managed beans. You gain performance but lose access to any JSF-specific data or methods on the server side. However, it is possible to share data between JSF and JSON-RPC-Java objects using the user’s HttpSession. To allow access to the HTTP request and session objects, any HttpServletRequest or HttpSession parameters to a Java method are automatically set by JSON-RPC-Java. To give another entirely useless example, this remote method would return the current user’s session ID:

class MyObject {
public String getSessionId(HttpSession session) {
return session.getId();
}
}

So far, JSON-RPC-Java has worked great for existing JavaScript components that pull their data from JSON structures, like Dojo’s FilteringTable or TreeV3 widgets. It does, however, require some effort and manual programming for communicating with the server and updating the data, and does not integrate with JSF. It depends on the use-case whether this is worth the trouble – for many common uses of Ajax (form validation, partial page rendering) this is possibly not the case, but when dealing with lots of data it might well be.

Comments (6)

Automated Browser Tests: Selenium IDE

Selenium is a collection of cross-browser, cross-system browser testing frameworks. It includes a client-side Javascript/HTML testing application and, for more complex tasks, a remote framework that can be used for automated browser access in a number of programming languages (e.g. Java or Python). Thus it becomes possible to write browser tests like ordinary unit tests in your favourite language, assuming that the targeted browser is available on the host system.

While I haven’t gotten around to using the remote framework yet (I’m really inclined to do this soon), I just discovered the Selenium IDE plugin for Firefox. It’s a macro-based web testing application that captures the user’s input on a webpage and replays it at a later moment. If an user action fails to execute, the test is aborted and an error message is returned. Tests can be exported to remote tests in any supported language, effectively providing people a way to write (read: record) remote tests without actually programming anything.

Unfortunately, my first attempts to record tests for an in-house application heavily dependent on Javascript and DHTML failed, yielding incorrectly captured input (e.g. frame names) or missing actions (e.g. clicks on Dojo tree nodes). However, for 1.0 web pages with little or no Javascript involved, it worked flawlessly.

At first glance, there are still some issues to be solved for testing arbitrary web applications, but the overall concept is promising and works well if Javascript is not critical to the execution of core functionality.

Leave a Comment

Dojo performance and parseWidgets

As much as I like the Dojo toolkit, its out-of-the-box performance leaves something to be desired. While the package system is very capable, the (synchronous) loading of missing widgets and classes via XmlHttpRequest is slow and usually misses the browser cache. This can be fixed by creating a custom Dojo build with all required files included in a single dojo.js file.

On a reasonably complex page another problem becomes obvious: the DOM parser Dojo employs to search for widgets in a HTML page seems to be rather slow. For example, on a page with several nested tables of about 40k this takes seconds on my machine, without a single Dojo widget actually being used on the page.

Apparently, the only feasible solution at this time is to set the parseWidgets init parameter to false and specify all Dojo widget IDs explicitly. For example,


var djConfig = { isDebug: false,
baseRelativePath: "/js/dojo/",
parseWidgets: false,
searchIds: ["dojoWidget1", "dojoWidget2"]
};

While not exactly user-friendly, at least this works without a noticeable impact on performance.

Leave a Comment

Sorting HTML Data in Dojo Tables

We learned the hard way that Dojo‘s SortableTable does not work too well with HTML data in its cells. It’s not sortable, and sometimes markup is discarded or ignored. Googling brought to light the FilteringTable, a clean rewrite with more capabilities and less quirks. It’s available in current 0.4 nightly builds and works pretty well. Its parameters are similar to the SortableTable widget, except that rowClass and alternateRowClass have not been implemented yet – so you have to use td and td.alt of your table class for alternating row styles.

Unfortunately the nightlies made something clear – initialization of a complete Dojo distribution is very slow. Importing a single widget class takes up to 3 seconds on a decent PC. Including all required widgets (about 3 or 4) into a single compressed dojo.js file improves initialization to about 300 ms, but it’s still noticeable and a major issue for a good user experience. I really do hope that Dojo initialization will be tuned considerably before 0.4 is released…

Comments (2)

JSF and Ajax: ajax4jsf

Assuming that the component model of JSF is pretty well suited for Ajax applications, I found it surprisingly hard to find an Ajax framework that

  • has native support for JSF and the JSF lifecycle (unlike generic frameworks like AjaxAnywhere),
  • requires no custom Javascript coding for basic event/update mechanisms, and that
  • supports existing components unaware of Ajax.

There is a proof-of-concept implementation of a very JSF-centric approach proposed by Jacob Hokoom that fully utilizes the JSF component tree in the jsf-extensions project. Very promising, but it seems to be in a very early stage and requires JSF RI 1.2.

An existing alternative is Ajax4jsf, a rather mature and capable Ajax filter created and maintained by the Exadel people. Usage is fool-proof: using the a4j tag library, you either attach Ajax behavior to Javascript events (e.g. onchange) of existing input elements, or you add command buttons that emit Ajax calls when clicked, instead of reloading the whole page. When an Ajax event occurs, the form surrounding the element is submitted, making server-side handling identical to that of a common post-back. Ajax4jsf tags accept a list of component IDs to be re-rendered when the Ajax call was processed, automagically updating independent regions of the page. You don’t even have to identify those regions manually, for example, if a datatable should be updated – pass its ID to a4j and it will be updated when the server response arrives.

My only gripe so far is performance – by default, every request is routed through a Tidy filter, even for non-Ajax pages. This can be disabled by setting the forceparser init parameter to false (in the web.xml filter definition), which will only tidy up Ajax responses.

Oh, and if you’re using Facelets: read the docs ;). Remove the Facelets view handler from your faces-config.xml and set the org.ajax4jsf.VIEW_HANDLERS context parameter in the web.xml instead.

Besides possible performance concerns, I believe ajax4jsf’s interface is pretty much perfect for ajaxifying JSF applications without special needs – that is, wiring client-side events to JSF beans and rendering partial updates of a page. I’m all for simple, straight-forward solutions that just work – which is also the reason I was slightly disappointed of Pro JSF and Ajax with its clumsy (but surely more flexible) mabon. I guess I just don’t want to write more client-side Javascript than absolutely necessary for a pleasing user experience.

Comments (5)

Ruby better than JSP?

Bruce Tate (of Beyond Java fame) wrote a combined JSP-rant/Ruby-for-the-web article in which he claims that

  1. JSP is crap (agreed),
  2. Embedded Ruby templates are better than JSP (no objection either),
  3. and thus that Ruby is better suited for web development than Java (huh?).

Ignoring the fact that JSP is outdated and many better alternatives exist (Facelets, Tapestry, Freemarker, …) and that there’s even Groovy Templates, I don’t see the ruby templates/components described as something desirable. They’re great for hacking small webapplications, but each line of code embedded in a template/component inevitably creates maintenance problems. Sure, we do need looping and conditionals for templates, as well as output formatting routines – but that’s it, and you don’t need Ruby or Java for such a task. Code inside a template is hard to debug, hard to test, and hard to refactor.

Seaside, a Smalltalk-based web application framework, looks pretty interesting from a programmer’s point of view, but I doubt any non-programmer will adopt to that way of thinking:

renderContentOn: html
	html heading: 'Hello world' level: 1.
	html paragraph: 'Welcome to my Seaside web site.  In the future you
		will find all sorts of applications here such as: calendars, todo lists,
		shopping carts etc'

It looks great – for a programmer, and as long as your designer colleague can get his job done using pure CSS. I’m not too sure Smalltalk will take off for web development as did Ruby, but it would be interesting to see more work done in this direction for other languages (in contrast to HTML templating).

Overall, Bruce Tate’s conclusion that “other languages such as Ruby handle Web development much better than Java technology” is not supported by his article. However, this doesn’t make Ruby on Rails any less impressive than it already is – for anyone doing web development, regardless of his/her language of choise.

Comments off