Groovy + JSON + Prototype in Action [English version]

Рубрика: Development, Groovy, Java, JavaScript/Ajax | 27 July 2007, 14:57 | Vadim Voituk

I’ve heard an opinion that Groovy is good only for simple utilities and prebuild scripts. In this note I’ll try to prove that this is not the way things done in a real world. I’ll try to use Groovy with a couple of popular Web 2.0 technologies.


Let’s say that we need to develop a simple service that should retrieve user info from a database. Just to add some fun – we’ll get it as a Json object.

So, here’s the plan:

  1. Collect the requirements
  2. Create a dummy database
  3. Create a connection pool
  4. Describe User entity
  5. Create a servlet that should give us some info in Json format
  6. Create a servlet that displays a user list
  7. Create a client side interface that communicates with servlet

That’s the tools I used for development:


First of all copy groovy-all-1.0.jar and mysql-connector-java-5.0.4-bin.jar to $TOMCAT_HOME/common/lib/.
Basically it’s quite enough to put them into WEB-INF/lib of your web project. But it didn’t work that way and I was too lazy to find the reason.

Copy commons-beanutils-core.jar , ezmorph-1.0.1.jar и json-lib-1.1-jdk15.jar to WEB-INF/lib of your web app.

Create a database and populate it with some data:
[sql]

CREATE DATABASE jwap; CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` char(255) NOT NULL default '',
  `email` char(50) NOT NULL default '',
  `b_date` date NOT NULL default '0000-00-00',
  `icq` bigint(20) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `u_name` (`name`)
) ENGINE=MyISAM;

INSERT INTO users (name, email, b_date,icq) VALUES
('Vadim Voituk', 'vadim@microsoft.com', '1980-11-22', 944328),
('Bill Gates', 'bill@microsoft.com', '1954-01-04', 123456789)

[/sql]
Create a connection pool. I’ll put it to jdbc/MYSQLDB. Edit META-INF/context.xml:
[xml]
<?xml version=’1.0′ encoding=’utf-8′?>
<Context>
<Resource
name=”jdbc/MYSQLDB”
auth=”Container”
type=”javax.sql.DataSource”
username=”mysql_user”
password=”my-mysql-password”
driverClassName=”org.gjt.mm.mysql.Driver”
url=”jdbc:mysql://localhost/jwap”
validationQuery=”SELECT 1″
maxActive=”150″
maxIdle=”15″
/>
</Context>
[/xml]
Describe User entity:
[java]

class User {
  int id;
  String name;
  String email;
  int icq;
}

[/java]
Just to mention: you can create a groovy servlet in two ways: subclass javax.servlet.http.HttpServlet or with GroovyServlet.
I’ll show you both.

Let’s create servlet that renders user info:
[java]

import javax.servlet.http.*;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import groovy.sql.Sql;
import net.sf.json.JSONSerializer;
class UserInfo extends HttpServlet {
/**
* @see
*/
public void service(HttpServletRequest request, HttpServletResponse response) {
  String id = request.getPathInfo();
  if (!id?.startsWith("/") || id?.length()<=1) return;
  id = id[1..id.length()-1];
  def numId;
  try { numId = id.toInteger(); } catch (NumberFormatException e) { return; }
  PrintWriter out = response.getWriter();
  InitialContext initCont = new InitialContext();
  DataSource dataSource = (DataSource)initCont.lookup("java:comp/env/jdbc/MYSQLDB");
  def db = Sql.newInstance(dataSource);
  try {
    db.eachRow("SELECT * FROM users WHERE id='${numId}'") {
        def user = new User(id:it.id, name:it.name, email:it.email, icq:it.icq);
        out.println JSONSerializer.toJSON(user,  ["metaClass"] as String[])
    }
  } catch (Exception e) {
    out.println("Error: " + e.message);
  } finally {
    db.close();
    out.close();
  }
}
}

[/java]
register it in web.xml:
[xml]

Return user info
UserInfo
com.point.heartbeat.UserInfo


UserInfo
/user/*

[/xml]
Now deploy your application and type: http://localhost:8080/groovy/user/1 … voila:
{"email":"vadim@microsoft.com","name":"Vadim Voituk","id":1,"icq":944328}
That’s how we managed to get a Json representation of User with id=1

That’s the “classic” way of making servlets. Now let’s add some “new school” stuff.


Edit web.xml:
[xml]
<servlet>
<description>Groovy servlet</description>
<servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GroovyServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>[/xml]
In your WebContent folder create a script:
[java]

import javax.naming.InitialContext;
import javax.sql.DataSource;
import groovy.sql.Sql;
response.setContentType("text/html;charset=utf-8");
InitialContext initCont = new InitialContext();
DataSource dataSource = (DataSource)initCont.lookup("java:comp/env/jdbc/MYSQLDB");
def db = Sql.newInstance(dataSource);
try {
  db.eachRow("SELECT * FROM users ORDER BY id") {
     out.println "

$it.name" } out.println ''' '''; } catch (Exception e) { out.println("Error: " + e.message); } finally { db.close(); out.close(); }

[/java]
Redeploy application and type http://localhost:8080/groovy/UsersList.groovy. The user list is here.

Now we’ll add some more UI-candy :-) We should display user info after click on user name. To do this I use prototype.js. Okay, you _can_ do it with plain javascript, but I’m too lazy, besides I don’t like to reinvent the wheel.

All javascript-related stuff will be done in separate file my.js.

That’s what we got
groovy-json-example.PNG

Full source code

That`s all. Keep Groovy!

Комментариев: 4

4 Responses to “Groovy + JSON + Prototype in Action [English version]”

Комментарии:

  1. dimat

    Something wrong with your code, because JS alert doesn’t show ICQ.

  2. vadim

    There were no UIN specified in database for this particular user

  3. Sey

    It’s is a good write-up but I think you should put in more details. Nevertheless it’s very informative.

  4. javadev

    It is terrible java code which makes java newbees never learn OOP and write spahetti code.

    You better separate HTML and SQL stuff.

Leave a Reply