Over a million developers have joined DZone.
Platinum Partner

Web Applications Development with Gaelyk

· Java Zone

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.

For a long time I wondered this: what is the best framework for small, experimental web applications?

I've been a Java programmer since 1996, and I can create a servlet or jsp with simple HTML, but I see a number of things as issues.

First of all - user management. Login / registration form, email etc   - I prefer to  spend as little time as possible on all those issues.

Second - hosting - Java hosting is expensive.

And finally I found a solution - it is Gaelyk: a Groovy framework for Google App Engine.

There are a number of ways to create simple Gaelyk project - you can download template project  and you can create a project using maven archetype, but both are using the standard groovy compiler (and not the eclipse groovy compiler).  Also, neither contain examples of object persistence.

So, I created my own maven archetype for Gaelyk. Let's use it to create a simple Gaelyk project:

mvn archetype:generate -DarchetypeGroupId=org.bernshtam -DarchetypeArtifactId=gaelyk-archetype -DarchetypeRepository=http://bernshtam.name/maven2 -DgroupId=myexample -DartifactId=test1 -DarchetypeVersion=1.0

Now you can import this project to Intellij IDEA.

After importing, do not forget to add App Engine facet to the project.  Now you can add a run configuration.

Pay attention, the Google App Engine development kit should be already installed and set in IDEA.

maven will bring the rest of the dependencies :) 

Let's run maven's "install" and ...

Now - launch! 

Yes! It is working! This is a simple application for the creation of notes with priority.

Let's look at the source code.

web.xml setup a servlet and filter for groovlets and templates (gtpl files)

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

            <!-- Set it to true for more details -->
            <!-- Remove the default "generated by" messages from the templates -->
            <!-- Output generation time in the HTML, see source page -->





appengine-web.xml is a Google App Engine descriptor. You need to replace test1-archetype with the name of your app engine application (if you want to deploy it) and create this application in the App Engine console before you deploy.


<appengine-web-app xmlns="http://appengine.google.com/ns/1.0-SNAPSHOT">

    <!-- Enable concurrent requests by default to serve requests in parallel -->

    <!-- If all your templates and groovlets are encoding in UTF-8 -->
    <!-- Please specify the settings below, otherwise weird characters may appear in your templates -->
        <property name="file.encoding" value="UTF-8"/>
        <property name="groovy.source.encoding" value="UTF-8"/>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />

    <!-- Uncomment this section if you want your application to be able to receive XMPP messages -->
    <!-- And create a file named jabber.groovy in /WEB-INF/groovy -->
    <!-- Similarily, if you want to receive incoming emails -->
    <!-- And create a file named email.groovy in /WEB-INF/groovy -->

    <!-- It it advised to keep this parameter to true -->
    <!-- as per the release of SDK 1.2.8, -->
    <!-- this should speed up cold startups of applications by 10% -->
        <exclude path="/WEB-INF/**.groovy" />
        <exclude path="**.gtpl" />

Now Gaelyk specific stuff. routes.groovy contains instructions on how to redirect HTTP requests.

get "/", redirect: "listnotes.groovy"
get "/favicon.ico", redirect: "/images/favicon.png"

Gaelyk is an MVC framework, so most requests will be forwarded to controllers, whose role in Gaelyk plays groovlets. You can see a full description of routes.groovy DSL here .

Let's look now to the class Note:

package myexample

import groovyx.gaelyk.datastore.Entity
import groovyx.gaelyk.datastore.Key
import groovyx.gaelyk.datastore.Unindexed

class Note {
    @Key long id
    String login
    @Unindexed int priority
    String text

By default, Gaelyk offers you very simple integration with Google App Engine Datastore. It is not real ORM, not JPA, but you can use it for simple applications.

Let's see examples from this application controller:

Note  note = new Note(priority:priority, text: text, login: email)

def  note = Note.get(id)
def notes = Note.findAll { login == email }

Nice :) Isn't it?

Now let's look to variables user, request and log.

def email = user.email
log.fine("$notes ${notes.size()}")
String text = request.getParameter("text")

Those variables are not defined there. They are injected. user will contain null if a user is not logged in and will contain user details otherwise. log contains a logger and request contains HttpRequest object.

You will be excited by how many variables are automatically injected  into Gaelyk controllers, templates (and, if you wish, any other classes)

The model is passed from a controller to a view by request object properties:

request['notes'] = notes
forward "index.gtpl"

Templates are the last thing to see. They looks like jsp, contains % include % directives and code snippets.

<% include '/WEB-INF/includes/header.gtpl' %>

<h1>My notes</h1>

<% if (user) { %>

            <table width="50%" border="1">
                <tr><th width="30%">Note</th><th>Priority</th><th></th></tr>
                    <% request.notes.each { note -> %>
                        <tr><td>${note.text}</td><td align="left"> ${note.priority}</td><td><A href="deletenote.groovy?id=${note.id}">X</A> </td></tr>
                    <% } %>

    <div class="add">
    <h2>Add a new note</h2>
    <form name="addnote" action="addnote.groovy" method="post">

    Priority: <input name="priority" id="priority" type="number" value="1" min="1" max="10"/><br/> <br/>
    Text: <input name="text" id="text" type="text"/>
    <input type="submit" value=" Add Note "/></form>
    <% } else { %>
    <p><A href="${users.createLoginURL("/")}">Login</A> </p> to access your notes
<% } %>

<% include '/WEB-INF/includes/footer.gtpl' %>


Take a look how we check that a user logged in ( if (user) ...), how we retrive the mode ( request.notes.each ...), groovy style  of embedding variables ( ${note.priority} ), creation of login link ( ${users.createLoginURL("/")} - users is one more injected variable.

If you like Gaelyk - start by reading this tutorial!

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}