Spring Roo Tutorial: LongURL, Part 2

AttachmentSize
skeleton.roo1.8 KB

So in my last article in this series I talked about creating a basic REST server with Spring Roo. Here I start running the server and testing it.

Testing Option One

Let's try compiling it and testing it.

I am assuming that you have a Apache Tomcat java web server already installed. I fear that getting and installing it is outside the scope of this tutorial.

There isn't a specific build command as Roo normally builds automatically whenever necessary.
You can quit out of roo or open a new shell...

    mvn tomcat:run

This should build the system and send it to a tomcat which - by default probably runs on port 8080. Needless to say, if you already have something running and using port 8080 then this isn't going to run. Here is a way you can tell tomcat to run on a different port using the maven tomcat plugin

mvn -Dmaven.tomcat.port=8181 tomcat:run

In my opinion mvn gives counter-intuitive feedback. It normally says things like "unable to find resource: blah" when what it really means is "I've looked in my local repository for something, and can't find it, so now I'll try to fetch it from somewhere else". These messages are clearly labelled "[INFO]" instead of "[ERROR]" but they wind me up anyway.

If you get an error along the lines of "Missing: 1) com.sun:tools:jar:1.4.2" then you have a missing "tools.jar". I really don't understand how this got lost. I've seen the problem with OpenJDK. You can fetch the missing library and install it by following the instructions springRoo gives you. Or alternatively use a better, unbroken JDK from Sun/Oracle. *sigh*.

If it is all successful then you will get something like at the end of some logging:

    INFO: Initializing Spring FrameworkServlet 'longurl'
    27-Jul-2011 14:15:15 org.apache.coyote.http11.Http11Protocol init
    INFO: Initializing Coyote HTTP/1.1 on http-8080
    27-Jul-2011 14:15:15 org.apache.coyote.http11.Http11Protocol start
    INFO: Starting Coyote HTTP/1.1 on http-8080

If you don't get it then stop now and try to figure out what went wrong.

You should then be able to visit http://localhost:8080/longurl/ in your web browser and start to play with the interface you find there. Try creating a few records, listing them, delete one or two, and update them.

Testing Option Two

If you prefer to develop in Eclipse, and perhaps run Tomcat from Eclipse you can do that here instead of running "mvn" from the command line. Instead you run this command in Roo

    perform eclipse

And that builds a project which you can import into Eclipse. Hopefully it also runs the necessary maven code to fetch the desired jar files and put them into your local repository.

There are a number of Eclipse plugins that you need which I think I will have to leave out of this tutorial. Check the documentation. Basically you need something to help with AspectJ, and something to build maven. Hopefully you have that already.

Test Data

But beware. Don't get too carried away by filling in lots and lots of records. If you stop and restart the web server you will find your database wiped!
If you want this then fine, but if you don't then edit ./src/main/resources/META-INF/persistence.xml

You'll find a line like

    <property name="hibernate.hbm2ddl.auto" value="create"/>

So when you are happy with the database change "create" to "update" in the hibernate.hbm2ddl.auto line.

JSON / REST

Now ideally I just want to expose the UrlMap entities in a REST way so that if (for example) I request something like:

    GET http://myhost:8080/longurl/urlmaps/url_id
    Accept: application/json

then it returns a JSOn data structure corresponding to that shorturl. I can add something like that to my code with just one spring Roo command:

// Add ability to fetch the data through REST, returning json
json all

Woo Hoo! I never knew coding java was so easy. That one command just got springroo to do the following

Updated SRC_MAIN_JAVA/uk/co/owal/longurl/domain/UrlMap.java
Created SRC_MAIN_JAVA/uk/co/owal/longurl/domain/UrlMap_Roo_Json.aj
Created SRC_MAIN_JAVA/uk/co/owal/longurl/web/UrlMapController_Roo_Controller_Json.aj

What this has actually done is create a new MVC-style controller for receiving http requests for each type of entity in the system (ie each "table"), specifying either an individual record by its primary key, or all of them if no key is specified.

Test the REST part 1

Now, I don't know how you want to test the REST server. I found two ways that I quite like. You can try either of them, or use your own. The first I'll show you is to knock up a small perl script to make requests.

use strict;
use warnings;
use LWP::UserAgent;
use URI::Escape;

my $serverUrl = "http://localhost:8080/longurl/urlmaps/";
my @urls = (1,2);
foreach my $url (@urls) {
chomp($url);
my $ua=LWP::UserAgent->new;
$ua->default_header('Accept' => "application/json");
my $result=$ua->get($serverUrl . uri_escape($url), 'Accept' => "application/json");
print $serverUrl . uri_escape($url). "\n" , $url , "\n";
print $result->content;
print "\n--------------------------------------------------\n";
}

Easy, right?

Here is some sample output from somedummy records entered into the database.

http://localhost:8080/longurl/urlmaps/1
1
{"id":1,"longUrl":"bbb","shortUrl":"aaa","version":0}
--------------------------------------------------
http://localhost:8080/longurl/urlmaps/2
2
{"id":2,"longUrl":"eee","shortUrl":"bbb","version":0}
--------------------------------------------------

Test the REST part 2 - Using AJAX and ExtJS

Now I am sure that some people here don't like using perl. I don't understand their attitude myself, but in researching this I found a cool library from http://bti360.com which does something better. They have produced a number of screencasts which I recommend. You can fetch the accompanying code with this subversion command.

    svn checkout http://bti360.googlecode.com/svn/trunk/ bti360-read-only

The code we want is in

    bti360-read-only/screencasts/SpringRooDictionaryService/src/main/webapp/ExtJS

Copy that ExtJS directory from bti360 into our src/main/webapp directory.

Now, in Spring Roo shell run this command

    web mvc install view --path ext --title "Ext JS WS" --viewName index

You should get a response something like

    Updated SRC_MAIN_WEBAPP/WEB-INF/i18n/application.properties
    Updated SRC_MAIN_WEBAPP/WEB-INF/views/menu.jspx
    Created SRC_MAIN_WEBAPP/WEB-INF/views/ext
    Created SRC_MAIN_WEBAPP/WEB-INF/views/ext/views.xml
    Created SRC_MAIN_WEBAPP/WEB-INF/views/ext/index.jspx    
    Updated SRC_MAIN_WEBAPP/WEB-INF/spring/webmvc-config.xml

What this does is to provide a new menu item, with a jspx page for it. You should find the new pages in src/main/webapp/WEB-INF/views/ext

You probably want to test this now by launching it in tomcat as before, and visiting http://localhost:8080/longurl/ and looking at the new menu item "Ext JS WS". It doesn't do much yet. For that we need to put something into the web page.

I copied their index.jspx which looks something like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html xmlns:jsp="http://java.sun.com/JSP/Page" 
      xmlns:c="http://java.sun.com/jsp/jstl/core" 
      xmlns:tiles="http://tiles.apache.org/tags-tiles" 
      xmlns:spring="http://www.springframework.org/tags" 
      xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" > 
        <jsp:output doctype-root-element="HTML" doctype-system="about:legacy-compat" />
        <jsp:directive.page contentType="text/html;charset=UTF-8" /> 
<head>
    <link rel="stylesheet" type="text/css" href="/longurl/resources/ExtJS/css/ext-all.css"><!-- //required for FF3 and Opera --></link> 
        <script type="text/javascript" src="/longurl/resources/ExtJS/lib/ext/ext-base-debug.js"><!-- //required for FF3 and Opera --></script> 
    <script type="text/javascript" src="/longurl/resources/ExtJS/lib/ext/ext-all-debug.js"><!-- //required for FF3 and Opera --></script> 
        <script type="text/javascript" src="/longurl/resources/ExtJS/restTest.js"></script>
  </head>
  
  <div id="ext-placeholder">
  </div>
  
</html>

If you now relaunch tomcat with the updated system then you can access a debugging javascript screen which will let you push REST calls back to your SpringRoo web app - and you can see the responses. try using these for example

     http://myhost:8080/longurl/urlmaps/1
     http://myhost:8080/longurl/urlmaps/2
     http://myhost:8080/longurl/urlmaps/3

Reference

As an aside, if you want the full screencast from BTI360.com look at

* http://www.bti360.com/pages/page.asp?page_id=91491&articleId=18174
* http://www.bti360.com/pages/page.asp?page_id=91491&articleId=18691
* http://www.bti360.com/pages/page.asp?page_id=91491&articleId=13068

More later...