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.

Advertisements

6 Comments »

  1. JSON is good when you know the data structure in advance. Otherwise, the advantages might just disappear. Event the number of transferred bites vs XML might be increased.
    For example, you have a table with five columns. You can form the JSON data package that contain only the numbers or strings for table sell. The table itself can be created dynamically on the client side. Yes, the approach is clear, the result is good.
    However, what if you need not only show the numbers, but color some numbers that are exceed of the particular limit. Yep, you can add the additional data to your JSON package structure. Next, you need to have jsf input fields in the sell or sell contains other component with its own behavior. Only one approach you can use for common cases – to pack not only the data, but the layout. If you count the number of bite in the package, the result will not be so excited.

    Ajax4jsf works with abstractions. I.e. it does not know the structure of the component it can work with. At the same time, developing components based on Ajax4jsf we use JSON to transfer the data from server to client. In particular situation it really make sense.

    At the Q1 of this year, we are going to present the development environment that helps to develop rich JSF components. Some advantage features of the Ajax4jsf that are usually not used on the Application development level will be available there.

  2. Hi Sergey,

    Great news to hear about the component development framework. Regarding JSON and JSF components: you’re right, and that was also a point I was trying to make. As soon as there are server-side (JSF) components involved, you’re much better off with a generic framework integrated with JSF, such as Ajax4jsf.

    However, for pure client-side components such as those in the Dojo toolkit, JSON/RPC is a real alternative. It is very easy and efficient to feed data-oriented components such as the tree or table with JSON data, and it’s not (easily) possible to embed JSF components in these widgets anyway. Thus, if you’re willing to do without JSF in some parts of the application, JSON(/RPC) does offer advantages.

  3. simon said

    Great article

  4. nepoez said

    A4J allows for partial submit as well, see a4j:region and ajaxSingle attr and process attr. Not only do you get to partially render a page, u can also submit specific parts of the page. I’ve recently optimized a bunch of JSF pages that use A4J and even large tables can be partially rendered by specifying the specific rows you want re-rendered.

    So far the only thing I still can’t get good performance with A4J(richfaces) is adding/deleteing a row from a table, as it still has to re-renders the entire table instead of just appending a row šŸ˜¦

  5. Souhaib said

    Hi nepoez,
    I read your article and I’m a JSF beguinner and I’d like to use a4j to refresh a particular part of a page to get the result of an action.
    Would you like to tell how to do that using a4j or if there’s a tutorial that explain it.
    Thanks and Sorry for my English.

  6. you can also try Zen as a framework for doing AJAX with MultiValue BASIC as the server-side language and JavaScript as the client-side language.

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: