Sunday, February 18, 2007

Ajax Sandbox (1): Calling Remote Web Services
Play with Json and Java Json API


Json (JavaScript Oject Notation)i s a very interesting format for exchangingdata across domains. Comparing with XML,Jsont is easy to parse with JavaScript,and thus helps to establish a easy way to call remote web services from a Ajaxapplication.

Here is an example of providing web services in Json format by utilizing JavaJson API. There are three core components in this example: a POJO class (Book.java) which stores the data model; a Java servlet (bookWS.java ) which provides web services in Json presentation; A html page (bookWSTest.html) which shows how to call a remote web services in JavaScript using. The working environment is Netbeans 5.5 RC2 as IDE, glassfish v2 as application server.

Data Source

The data source is a POJO class (Book.java),which represents a data table "book" in the database:

id*
title
author
price
1
Java EE 5 Tutorial
John Smith
45.6
2
Ajax For Java Developer
Rayn Todd
29.0

Create a Web Services

The second component is a servlet (bookWS.java) which returns a list of books stored in the database. The result is in Jsonformat and is ready for a client to consume.

Before we go to further, let us take a look at the desired Json format in thisexample:

The following example shows the JSON representation of a object that describe onbook:


List A
:
{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1}

And the returned list of books look like:


List B
:
{"ResultSet":
{"books":
[{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1},
{"title":"Ajax For Java Developer","price":29,"author":"Rayn Todd","id":2}]
}
}

Now let's look at how we can utilize Java Json API to create web service in Json format.

The entity class in accessible via resource injection. A JPQL select query isused to select data from database:


String sql ="select object(o) fromBook as o"; //select all book indb

Query q =em.createQuery(sql); //executequery
ArrayList bookList = newArrayList(q.getResultList()); //store all books in alist
resultSet =getResults(bookList);


A private method is created to convert the list of books into a Json object by utilizing Java Json API:


privateJSONObject getResults(ArrayList bookList){

JSONArray items = new JSONArray();
JSONObject resultSet = newJSONObject();

JSONObject books = new JSONObject();

try {
for (int i = 0; i <bookList.size(); i++){
Book o =(Book)bookList.get(i);

JSONObjectbook_obj = new JSONObject();

book_obj.put("id", o.getId());
book_obj.put("title", o.getTitle());
book_obj.put("author", o.getAuthor());
book_obj.put("price", o.getPrice());
items.put(book_obj);
}

books.put("books", items);
resultSet.put("ResultSet", books);

}catch (JSONException e){
System.out.println("Error: Could not create Book JSONObject");
}
return resultSet;
}


The resulting Json object is then serialized and returned to client:


out.println(callback + "(" +resultSEt.toString() + ")");


"callback" is the name of callback function that can be defined by users' inputand retrieved by:


String callback =request.getParameter("callback");


Don't forget to set up response content type as:


response.setContentType("text/javascript;charset=UTF-8");


We have done all the work in Java servlet. When the servelt receives a request like: http://www.myServer.com/beanTest/bookWS?callback=resultHandler

The returned results should look like:

resultHandler(
	{
"ResultSet":
{
"books":
[
{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1},
{"title":"Ajax For Java Developer","price":29,"author":"Rayn Todd","id":2}
]
}
}
)

Let us go to next section to see how the results is accessible in JavaScript.

Consume Web Services

We use dynamic scripting tag to make a remote web service call. The returned Json object is accessible in the call back function. Here is a sample html page (bookWSTest.html):


<html>

<head>
<title>AjaxRemote Web Services CallTest</title>
</head>
<script>

functionloadPage(){
var url ="http://www.myServer.com/beanTest/booksWS?callback=resultsHandler";
varheadTag =document.getElementsByTagName("head").item(0);
varscriptTag =document.createElement("script");
scriptTag.src = url;
headTag.appendChild( scriptTag );
}

function resultsHandler( resultsObj){
var result =document.getElementById("result");
result.innerHTML= " total number of books is : "+resultsObj.ResultSet.books.length;
}
</script>

<bodyonload="loadPage()">
<divid="result"></div>

</body>

</html>


When page loads, function loadPage() gets executed and write a script tag forthe web services. Inside callback function resultsHandler, the returned Json object is accessible. In this example, the total number of books in db is printed out.



References:

  1. Introducing Json
  2. Json
  3. JSON and the Dynamic Script Tag: Easy, XML-less Web Services for JavaScript
  4. Ajax for Java developers: Java object serialization for Ajax
  5. JSON in Java











Friday, February 9, 2007

Grails -- Using Embedded Derby Database

Apache Derby is a relational database implemented in Java. It is light-weighted and can be easily embed it in any Java-based solution. Here is a summary of using Derby Embedded JDBC driver within Grails framework. I used grails-0.3.1 for the time being.

Section 1: Install Software:

1.Install Apache Derby (v10.1.3.1)

Follow the tutorial from http://db.apache.org/derby/papers/DerbyTut/index.html to download and install software. (Note: ij tool is great to run SQL query from command line).

2.Install Grails (v 3.0.1)

The installation instruction can be found here. Set up environmental variables as described in the tutorial.

Section 2: Configure Grails for Using Embedded Derby Database

Inside $GRAILS_HOME, create sample application.

1. Create new Grails application by run command grails create-app, set up corresponding application name as myTest. Run command “grails create-domain-class”, set up domain name as “Book”.

2. Copy derby.jar and derbytools.jar from $DERBY_INSTALL to myTest/lib.

3. Configure data sources. In myTest/grails-app/conf, there are three data source files:

  • DevelopmentDataSource.groovy
  • ProductionDataSource.groovy
  • TestDataSource.groovy
We need change the settings to let application talk to Derby instead of default Hypersonic database. A sample setting in ProductionDataSource.groovy would look like:


class ProductionDataSource {
boolean pooling = true
String dbCreate = "update" // one of 'create', 'create-drop','update'

##note: this setting point to a embedded db in /opt/db-derby-10.2.1.6-bin.
##The file could be anywhere that the application can reach
String url = "jdbc:derby:/opt/db-derby-10.2.1.6-bin/derbyDB"

String driverClassName = "org.apache.derby.jdbc.EmbeddedDriver”

String username = ""
String password = ""
}


4. We need another file in myTest/grails-app/hibernate/ called hibernate-dialects.properties which looks like:


DerbyDialect=Apache Derby


This file is required especially for Derby DB but not for Postgresql as I know.

Section 3: Run Application:

1. Then we are ready to run the application, execute the command:

grails run-app.

If everything goes right, we should be able to launch the application from http://localhost:8080/myTest.

2. To test the application by create some new records.

3. To verify whether the records are in Embedded Derby database, user Derby ij tool to run SQL query against our database prodDB. Please note, Derby won't allowed access from multiple applications for embedded model, so we have to shut down our application in order to run ij tool.

References
  1. Apache Derby Tutorial (http://db.apache.org/derby/papers/DerbyTut/index.html)
  2. Apache Derby Downloads (http://db.apache.org/derby/derby_downloads.html)
  3. Grails Installation Instructions http://grails.codehaus.org/Installation

Monday, February 5, 2007

Grails -- Interceptors in Grails

Introduction

An Interceptor is one of the key components in Aspect-Oriented Programming (AOP). It is defined to intercept method invocations, constructor invocation and field access. In grails, there are only two types of interceptor: beforeInterceptor and afterInterceptor. They both are action interceptors used inside controllers.

Examples

befoerIntercetor

This simple interceptor intercepts an user's request and checks uploaded file content-type. If it is not a PDF file, then it redirects the user to a previous view and presents an error message and returns false to caller. The innovation of the method is terminated; If yes, it continues the method call and trigger an action. It is very easy to use, no any configuration is needed.

class myController {
def update = {/** do something here **/}
def save = {/** do something here **/}

//This line defines which actions is going to be intercepted.
def beforeInterceptor = [action:this.&validateFileType,only:['update', 'save']]

def validateFileType = {
def myFile= request.getFile("myFile") //get uploaded file
if (myFile!=null && !(myFile.isEmpty()))
{
def contentType = f.getContentType()
if (contentType!="application/pdf"){
flash.message = "File must be a valid PDF file"
redirect(action:create) //if fails, redirect to previous page.
return false //This will terminate method call
}
else {
...
...
return true
}
}
else {
...
...
return true
}
}
}

In the line

def beforeInterceptor = [action:this.&validateFileType,only:['update', 'save']]

"only" is called “condition”. The condition of an interceptor can be either "only" or "except". If the condition is not defined, then all actions in the controller will be intercepted.

afterInceptor

The second interceptor is afterInterceptor. Unlike beforeInterceptor, afterInterceptor gets invoked after an action has executed and before response gets back to client. We can process response object inside afterInterceptor before it gets back to clients, for example, writing logs, compressing files, sending emails, etc.

The usage of afterInterceptor is very similar to that of beforeInterceptor. In my previous posting Grail -- How to Send Out Email After Some Actions Have Been Finished, I have posted an afterInterceptor example. I would like to save some space here.

Commentary

In grails, it is quite easy to use action interceptors to intercepts process based on either request or response. And it is also quite flexible to define which actions would trigger interceptors. No any XML configuration needed, which is the promise of coding by convention.

However, there are still some limitations here. As I know for the time being, an interceptor can only intercepts actions from the same controller instead of multiple controllers. In other words, no interceptor chain is supported in Grails current releases. Despite of this, I still want to say: the interceptors are so cool!

References

Grails Tutorial#Controllers (http://grails.codehaus.org/Controllers)