Spring Roo Tutorial: LongURL, Part 1
A little while back I needed to create a simple server to supply some information to some local machines, and cache that information. I realised that it was probably a project I could use Spring Roo to great effect, and that it was simple enough to provide the basis for a tutorial. Here is that Tutorial
I am processing URLs and want some way of identifying whether they are the same. Now there are reasonably well understood algorithms for normalising URLS - such as removing sessions after a semi colon, removing extra slashes, removing "/dirname/.." and so on. But many systems nowadays use URL shorteners - websites which provide a short URL which can be used in a browser to get to the longer URL web page. This is most common on Twitter where message length is restricted.
Now I could write some code which fetched each URL in turn and figured out whether it was redirected to some other web page but that would be pretty innefficient. My thought was to set up some kind of local server which acted as a memory store for all these short to long URL maps - and also figured out new ones.
I looked around for who else had done this sort of thing and found a web site called http://realurl.org/ This did most of what I wanted - but I still needed to cache its responses in one place so that I didn't ask it the same question 20 times. (You can find out more about their API at http://realurl.org/api.php )
I would need a database to store the mappings from short to long url. I would need some means of accessing those entities in a CRUD like manner, and I would need a JSON like call to fetch values from the database by specifying the "potentially" short url, and look them up on realurl.org if they were not found in our database.
I'd also cache the result whether or not the new url was shorter.
I wont show you how to set up Spring Roo. There are lots of tutorials for that. But basically you need to have roo shell (or Spring Tool Suite - STS) installed so that you can run roo in a new directory.
Use your favourite database tool to create a database, and user with permission to access that database. Personally I like phpmyadmin. The new user will need to create tables so don't skimp on the permissions :-)
I used MySQL, but you are welcome to use something else in your own projects - just don't come to me looking for free support when RANDOM_WEIRD_DATABASE doesn't work.
In my example I created a database called "roo_longurl", an user called "roo".
So, start up roo...
Create the Project
Let's create the project
project --topLevelPackage uk.co.owal.longurl --java 6 --projectName longurl
Cool. Hopefully that will have created some classes and a pom.xml file (for maven) in your current directory. Note that I have chosen "uk.co.owal.longurl" as the package, and "longurl" as the project name. Later on when you see the "~" symbol Roo treats that as short hand for the package name - so I don't have to type uk.co.owal.longurl every few minutes.
Sadly it is not easy to change stuff within roo. Some things you can change manually with a text editor / programmer's IDE and roo will notice and act accordingly. But often if you mess up you will need to start again.
Now, let's add some logging. I'm told that logging is a good idea, but I never use it because my code always works perfectly first time.
// Setup logging logging setup --level DEBUG --package ROOT logging setup --level DEBUG --package PROJECT properties set --name log4j.properties --key log4j.appender.R.File --path SRC_MAIN_RESOURCES --value longurl.log properties set --name log4j.properties --key log4j.rooLogger --path SRC_MAIN_RESOURCES --value DEBUG properties remove --name log4j.properties --path SRC_MAIN_RESOURCES --key log4j.appender.stdout properties set --name log4j.properties --key log4j.logger.sample.roo.longurl --path SRC_MAIN_RESOURCES --value DEBUG1
This puts most of the logging to a file, and stops it all being pushed to stdout. I'm not happy about this and suspect I've got something wrong.
Add the Database
// Setup Database. I guess it assumes localhost and default port.... persistence setup --provider HIBERNATE --database MYSQL --databaseName roo_longurl database properties set --key database.username --value roo database properties set --key database.password --value asarin // Sometimes I need to change the jdbc connection string found in database.properties
If you are doing this for the first time then you will probably find that Spring Roo doesn't know how to talk to MYSQL. "wtf" I hear you cry. It used to before, didn't it? Well, the ability to talk to MySQL was not deemed to be core to SpringRoo, but more of an "addon". We need to fetch addons from the public RooBot server. (Think perl CPAN, or java Maven repository)
For now I suggest you try following the instructions that Roo gives you.
Add the Entities / Table
We only have one entity in the system right now - and that is a UrlMap from short url to long url.
// Set up main table, with two main columns, and a numeric id. // To be honest the shortUrl ought to be the primarykey entity --class ~.domain.UrlMap field string --fieldName shortUrl --column SHORTURL --notNull field string --fieldName longUrl --column LONGURL --notNull
Hibernate and SpringRoo seem to like numeric primary keys. Ideally I'd prefer shortUrl to be the key since it should be unique in the table. But let's leave it like that for now.
Now, let's ask Spring Roo to create the main web application for this...
// Create Apache Tiles and Spring MVC scaffolding web mvc setup web mvc all --package ~.web
I've put it in a package called "uk.co.owal.longurl.web" (remember that ~ means the top level package).
This creates some basic jspx/html to be used in the web site.
Coming soon... testing what we have so far.