BT
x Your opinion matters! Please fill in the InfoQ Survey about your reading habits!

Your First Cup of Web 2.0 - A Quick Look at jQuery, Spring MVC, and XStream/Jettison

Posted by Joel Confino on Sep 15, 2008 |

No More Page Refreshes: use jQuery!

Here's an open apology to users of web sites I helped build: “Sorry I made you suffer through unnecessary page refreshes.” That's the first thing that popped into my head after learning about jQuery earlier this year.

jQuery is a powerful yet unobtrusive JavaScript library with a lousy name. It's concise, very readable syntax has me exciting about writing JavaScript again. It's unobtrusiveness makes it easy to add rich behavior—such as background form submissions—to web applications with very little modification of existing code. Being unobtrusive is particularly important when you are working with a large code base, or where extensive refactoring just isn't going to get funding. My boss is not going to give me 4 weeks to go back and add some visual goodness to an existing site. But I might get 4 hours, and that's where jQuery can help.

As a simple example, imagine an automobile search function that returns results based on a vehicle Model. Enter text into the field, click submit, and the results are displayed. The JSP might look like:

After the user enters a name and clicks submit, the entire screen turns white while the page refreshes and then the results are displayed. This is not a good user experience. Now, let's use jQuery to improve that experience by refreshing only the part of the page that actually needs to change. The modifications made to the existing page are:

  1. Split the search form and search results into 2 separate JSPs so the results can be displayed separately, without having to re-render the search form.
  2. Add a placeholder <div> on the search form JSP to hold the search results.
  3. Add a line of jQuery that submits the search form in the background using AJAX, placing the results in the placeholder <div>.

The resulting code looks like this:



When the user enters a name and clicks submit, only the search results <div> will refresh. The user experience is improved, and we didn't have to write a lot of JavaScript. Let's look at the jQuery script fragment in a little more in depth:

The code reads:

Line 2 -- “When the page gets loaded...”

Line 3 -- “Select a form with an id= 'searchForm', and make it AJAX-enabled (submit in the background)”

Line 4 -- “Use POST as opposed to GET”

Line 5 -- “Puts the results in a DIV with an id of 'searchResults'”

Lines of jQuery code start with “$()” and always select an element such as “document” or “#searchForm” to operate on. jQuery acts like a decorator and allows you add all kinds of interesting behavior to elements such as AJAX-enabling forms, visual effects, drag-and-drop, and more.

The example shows a lot of functionality baked into a couple of lines of code, and demonstrates why I like jQuery: the decorator approach makes it ideal for enhancing existing web apps. Rather than rewriting existing HTML, you can apply jQuery to decorate it and add new behavior.

Returning data instead of HTML using Spring MVC and XStream/Jettison

In the first example, jQuery was used on the client, but nothing significant was changed on the server. We still kept the basic flow, which involved the user clicking on something in the browser, a server request being created, and HTML being returned. But what if the server can return data in the form of JSON or XML instead of HTML?

Returning data rather than renderable HTML allows the client to potentially cache the result, which reduces the number of server requests. Data is potentially more terse than HTML—this also reduces the size of the result when it needs to be returned. Look at the following example:

In the standard flow, three user interactions with browser result in three server requests. Now let's look at an optimized flow where the server returns data instead of HTML:

In the optimized flow, three user interactions only generated one server request.

There are many potential data formats that can be returned by the server. Which one to select depends on the situation. Some options and reasons for selecting them:

Server Response Format When to Use Frequency of Use
Entire HTML pages Initial page load Low
HTML snippets Places were server-side rendering is easier or necessary. For example you're rendering a table with the popular <displaytag> tag library. Low
JSONB

{
  "car": {
      "id": "5",
      "make": "Acura",
      "model": "MDX"
  }
}
Good general purpose data format that can be used for most server responses. Concise and easy to work with in JavaScript. High
XML

<car id="5">
     <make>Acura</make>
     <model>MDX</model>
</car>
Complex data that cannot be easily represented in JSON. XML's structure contains elements and attributes, while JSON only has elements. Low

Let's look at a code example where the server returns JSON data to the browser. Let's replace the original car model search page with a page that includes both a make and model drop-down. When the user selects make, the models for that make are populated. When the user selects a model, a table listing the available model years is populated.

Starting on the server side, we will see how we can use Spring MVC along with XStream and Jettison to serve up JSON data. First we'll build a Spring MVC controller:

Line 1 – The @Controller annotation tells Spring MVC to use this class as, you guessed it, a controller

Line 4 – The @RequestMapping annotation maps the request URL to the handler method

Line 6 – A ModelAndView object is created with a view name of “carselector” which will get mapped to carselector.jsp

Line 7 – A list of Makes is added to the ModelAndView using the key “makeList”. This object will be available in the JSP using the expression: ${makeList}

Line 11 – Again, the @RequestMapping annotation maps the request URL to the handler method

Line 12 – The @RequestParam annotation maps a request parameter to a method argument

Line 13 – This ModelAndView is created using a simple JSON-rendering View class that I wrote called JsonView. Spring MVC makes is quite easy to write custom views, and JsonView is where XStream gets hooked in.

Line 14 – A list of Models is added to the ModelAndView using a key that is expected by JsonView.

In summary, the controller responds to two URLs, “carselector.html” and “models.html”. It renders an HTML page as the response to the “carselector.html” URL, via a standard JSP view. Let's take a look at the JsonView class, which renders the JSON result for the “models.html” request:

Line 4 – XStream is instantiated using the JettisonMappedXmlDriver to output JSON instead of XML

Line 6 – Spring MVC View classes must implement a render() method

Line 9 – Get the data out the model that was created by the controller

Line 11 – Actually generate the JSON (despite the fact that the method is named toXML)

It really is that easy. The XStream library also includes a set of annotations that you can place on your domain or transfer objects to provide hints on how to render the JSON, but in general the library works with minimal configuration.

Now the server is generating JSON, but how does the client use it? For that answer, we'll look at jQuery again. Remember, there are 2 events that we need to handle: selecting a value from the “make” dropdown populates the “model” dropdown. Selecting a value from the model dropdown populates the model year table. Here's the jQuery ready function that sets up the event handlers:

The “select[name^=make]” expression looks a lot like a CSS selector, and that's because jQuery selectors are a super set of CSS selectors (kind of like if CSS and Regex had a baby together). These expressions are very powerful, and can be used to select single or multiple items at a time. In this case, the expression reads, “Select a <select> element whose name attribute is 'make' and bind the loadModels function to the change event". Every time a user selects a value from the dropdown, the change event is generated by the browser, and the loadModels function will get invoked.

Now let's take a look at one of the event handlers:

Line 2 - The getJSON method will perform a AJAX request and expect JSON returned by the server. It requires 3 parameters: the request URL, any request parameters, and a callback function to invoke once the server responds.

Line 4 - The callback function is a closure. Closures in JavaScript are similar to anonymous inner classes in Java, and they are very useful to use as callbacks. Notice that this function expects the JSON returned from the server to be passed in as a parameter.

Line 6 - At this point we need to know a little bit about the structure of the JSON we're working with. In this simple example, the model data is structured as the following:

The code at line 6 reads, "For each model..."

Line 7 & 8 - Construct an element from each model

Line 10 - Select the <select> element where name=model, and replace the option list with the options that were just constructed.

With the bare minimum of JavaScript, we were able to:

  • register an event handler,
  • get JSON data asynchronously
  • update the options in a dropdown based on that JSON.

That's powerful stuff, and one of the reasons I really like jQuery. Now what about caching? It is a trivial case to add an "if" statement prior to the getJSON call to see if the result already exists in cache. There is a nice little jQuery plugin called jCache that you can use.

Conclusion

jQuery + Spring MVC + XStream/Jettison provides a really nice stack to rapidly develop web applications that cleanly separate data and presentation, provide the user with a better experience, and potentially improve performance along the way. Are there other high-quailty frameworks that can help you do this? Sure, but I like the combination of jQuery, Spring MVC and XStream/Jettison, and I feel each are "best-of-breed" in their particular niches.

YOu can download the full example code HERE.

About the Author

Since his first Java assignment, printing reports with Java 1.02, Joel Confino has been hooked on Java technology. He has been working on distributed systems, various web architectures, and JEE design and programming for the past 10 years. Confino has consulted at many large financial services and pharmaceutical companies, and helped them use Java to expand their business and reach their customers with sophisticated web-based systems. He is currently a Java architect at Chariot Solutions.

About Chariot Solutions, LLC

Chariot Solutions is an IT consulting firm specializing in application development and systems integration using Java and open source technologies. Chariot consultants include some of the top software architects in the country, all of whom possess a rare combination of deep technical expertise, applied industry knowledge and a genuine love for what they do. Chariot's consulting team has made the company the optimal partner to design, develop, deploy, integrate, support and tune mission-critical systems for companies of all sizes. Visit Chariot on the web at www.chariotsolutions.com.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

How does this compare to the Ajax support that is in Spring MVC? by Jacek Furmankiewicz

I was just reading that Spring MVC 2.0 added a whole Javascript support module (based on Dojo).

How would you describe your jQuery option compared to that default functionality?

Re: How does this compare to the Ajax support that is in Spring MVC? by Solomon Duskis

The Spring MVC JS support that you're talking about is based off of Spring 2.5+. I built something similar to Joel's framework. I've also looked into the Spring-JS stuff that's in the Spring Web Flow package.

Basically, Spring-JS is an integration between Spring MVC and Tiles that only renders a partial HTML fragment rather than the whole page. The JS/Dojo portion calls the original controller and tells it which parts to render, and then how to place that HTML fragment back into the current page. Spring-JS is not in the Spring core package, and has to be downloaded as part of the Spring Web Flow package.

Joel's approach uses JSon rather than HTML fragments. It also uses JQuery's built in DOM manipulation. It's more network friendly, but you may end up with more cross-browser issues, since you're doing a lot of DOM manipulation. JQuery handles a lot of issues, but not everything.

JQuery seems to be a favorite of UI developers who are more comfortable in JS. Dojo seems to be a favorite of the Java/back-end guys.

Authentication by Gabriel Silva

Hello,

What if user looses his/her session and then tries to use the system. How would you handle such situation? Is there any built-in solution in JQuery to handle that?
Thank you for the article.

Re: How does this compare to the Ajax support that is in Spring MVC? by Joel Confino

Thanks Solomon for the good summary of Spring JS. I am new to Spring JS myself (2.0 was just released in April), but I agree with your assessment.



So how do jQuery and Spring JS compare? I think they overlap. jQuery is more flexible and general purpose, but Spring JS looks promising and provides some features that jQuery doesn't (more on that below).



Spring JS is geared towards the server returning HTML snippets. That architecture has advantages and disadvanges like any other. One really nice advantage is that Spring JS will degrade nicely if the browser doesn't support JavaScript. jQuery can also be used to return HTML snippets, but obviously can only function in browsers that run JavaScript. While Spring JS currently uses Dojo as the underlying JavaScript framework, the documentation states that jQuery *may* be supported in the future -- guess we'll see.



I personally like the server returning data instead of HTML, and to do that you'll need a framework like jQuery or Flex or GWT on the front end. A major advantage of that architecture is that the UI and server are completely decoupled. The XML/JSON document becomes the contract between them, and often the server implements a REST-based API. This allows them to be developed on different schedules independently. So UI folks can immediately develop the UI using a static XML file for data and don't have to wait for the server to be developed. Likewise the server can be developed and tested without needing the UI.

Re: Authentication by Joel Confino

Just to expand your question a little bit, I'll rephrase it as, "What happens when you make an AJAX call and you are not authenticated with the server?"



In my experience there is no built-in standard solution in jQuery to handle authentication. However the custom solution is not too difficult. After making an AJAX call, you check the server response in a callback function. If the response from the server is "Hey you're not authenticated" you show the user a login dialog or something, and send the username/password to the server in another AJAX call. It is actually quite common to need to do some custom stuff before and after AJAX calls (like checking the response for something after a call or checking a local cache before making a request), and jQuery is extensible and makes it easy to make your own custom functions and have them be available in the jQuery "$." namespace. So instead of calling jQuery's $.getJSON function you call your custom $.getJSONCustom function which does additional work and delegates to jQuery's $.getJSON for the actual AJAX call.

Example Code Posted by Joel Confino

I posted the full example code at: www.chariotsolutions.com/code_samples/car-demo-...

Comparison to other JSon/Data Server side technologies by Solomon Duskis

There was some discussion about Browser-side technologies (Dojo vs. JQuery). I'd also like to throw in some other technologies that can return server-side JSon/XML and integrate with Spring MVC:




1. The next version of Spring 3.0 MVC will have more support to do this, including more "RESTful URLs." The current model is limited to "/models.html?modelId=1010." Spring MVC 3.0 will allow you to map "/models/1010.json" to your controller. All of this is still in progresss, but it has to be out before Spring One - just take a look at all of the Web and REST sessions in the schedule

2. JAX-RS - It's a JEE standard API for "Web Services." It has a similar annotation-driven model. Jersey, the reference implementation of JAX-RS, integrates with Spring. It has the concepts of JSonView, XmlView, YourOwnView, already built in

3. DWR - Direct Web Remoting. It's a framework that's been around for quite a while. It has a server-side component and it's own JavaScript framework. It has some pretty advanced performance and security features

Re: Comparison to other JSon/Data Server side technologies by Ayan Barua

Might be bit of a stupid question here, but will this work with Hibernate 3+?

I am looking at a jquery/jsonview/spring/hibernate/mysql stack hence the question.

We tried to use JSONView from another project and apparently there were some conflicts.

What is your take on this architecture? I would much appreciate if you throw some light on this.

Thanks
Ayan

Questions by Ilan M

1. I understand that the demo carsearchresults.html is ajax with out JSON. Correct?
2. I tried to the same as the carsearchresults.html example in my code. The action took place, it returned to the url with carsearch.html page but showning only the context of carsearchresults.html. Do you have an idea what I have to do? The only different in my code is that I am using a formcontroller.

Download lInk by Carlos Tevez

hello, could you please update the download link?
it doesn't work anymore.
I'm really interested in the example code.

Thanks
reseba

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

10 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT