Part 1: Getting Started (again): Build A Web App With Spring Boot

As the latest in a long line of enhancement to the Spring framework aimed at eliminating boilerplate code and decreasing the time spent by developers setting up a new project, Spring Boot serves its purpose well. In this installment, I’ll walk through getting a project off the ground, rehashing much of what is covered in the first Spring-Boot starter guide on the Spring.io site. This will serve as the basis for upcoming installments. In this series, I’ll be using Java 1.7, Gradle 1.11, and Spring Boot 1.0.1.

Setting Up

There are Spring Boot starter versions of several different projects: web projects, data projects, integration projects, etc. Here we’ll be starting with the Spring Boot web project.

The first step is configuring your project’s directory structure. Spring Boot, whether you’re using Gradle or Maven, both follow the classic convention for directory naming and source structure. Create an example project using the structure below, substituting values in square brackets with your own:

[project-name]/src/main/java/[package-name]

In the root of our project, we’ll create a new build.gradle file:

[project-name]/build.gradle:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.1.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'getting-started'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "http://repo.spring.io/libs-snapshot" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")

    testCompile("junit:junit")
}


task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

Several items to mention here:

The ‘buildscript’ closure sets up the build itself. This is where the plugins used by the build are declared, along with the repositories in which they can be found.

Following that, there are several plugin applications.

  • The java plugin provides the basic tasks related to a simple java project – compiling and packaging, among others.
  • The eclipse and idea plugins allow project files to be created for eclipse and Intellij, respectively.
  • The spring-boot plugin contains tasks that build executable jars and execute them using embedded tomcat using tasks
    like ‘bootRun’, which we’ll use often in these tutorials.

Next the ‘repositories’ closure is used to declare where the project’s dependencies will be found.

After that, there is a ‘dependencies’ closure that contains the jars required by the project

Last, there is a standard gradle pattern – the task wrapper – which is used to enforce the version of gradle being used on the project, as well as allow easy execution of the build by users who do not have gradle installed. More information on that found here.

Application Configuration

In the source root of our project ([project-name]/src/main/java/[package-name]), create a file called ‘Application.java’. This file mirrors the one found in the first Spring-Boot tutorial, but since it serves as the foundation for upcoming tutorial sections, I’ll call out a few things already explained on the Spring.io site:

[project-name]/src/main/java/[package-name]/Application.java:

package com.rodenbostel.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

You’ll notice two major components of this file: the annotations, and the main method.

The annotations are marker interfaces used to alert the framework that this is a Spring config file (@Configuration), that you’d like to scan for beans to load in the current and child packages (@ComponentScan) and that you’d like to use auto configuration settings (@EnableAutoConfiguration). Auto configuration in Spring Boot takes the concept of convention over configuration to an almost Rails or Grails-like level. It provides basic configuration of an application – where to find properties files, how properties files are named when using Spring Profiles, configuration a DispatcherServlet (note the lack of web.xml), and much more. It is worth it to look further into what auto configuration is providing to insure your application does not conflict with it, especially if you’re planning on deploying to containers that also provide libraries on the class path by default (I’m looking at you, Websphere).

The main method simply allows the application to be executed from the command line. This includes the startup of your embedded container (in our case, Tomcat). It’s worth mentioning here that the return type of SpringApplication.run is an ApplicationContext object which can be further manipulated.

Creating a Controller

Again using the similar source to that of the Spring Boot demos on the Spring.io site, we’ll begin developing our app using a sample controller configuration as a RestController to verify our app is functioning correctly. In our source root ([project-name]/src/main/java/[package-name]), create a file called ‘SampleController.java’.

[project-name]/src/main/java/[package-name]/SampleController.java:

package com.rodenbostel.sample;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }

}

Here we are using constructs familiar since Spring MVC 3.5-ish. The RestController interface declares just that – a RESTful controller. This controller will return strings instead of views by default. The RequestMapping annotation on the only method in this class should be familiar, too. This calls for the controller to respond to requests at “/“ by executing the index() method. In this case, we’re responding with a simple String.

Execution

For this introduction, and the tutorials that follow, I’ll be using ‘gradle bootRun’ to execute the app. Upon executing ‘gradle bootRun’, in a browser, visit ‘http://localhost:8080/’, and admire you’re work. You should be looking at a simple string: ‘Greetings from Spring Boot!’.
Screen Shot 2014-04-07 at 9.21.09 PM

Preparing for Part 2

Again, this post re-hashed most of what is found on the Spring.io site on the same topic. I hope this has included some additional insight that will help get you started. Since this will be the foundation for Parts 2 and beyond, the code up to this point can be found on Github. The next installment will start where this post left off. Check back soon for the next installment: Adding views using Thymeleaf.

Advertisements

Beyond The Examples

In the last several years, rapid web application frameworks have been most developers first choice when starting a new project. Rails and Grails have taken the concept of convention of configuration to extremes, eliminating boilerplate code, and allowing developers to create web applications more quickly than ever. The latest incarnation of Spring and its related tools go far in emulating this kind of productivity. Spring Boot and it’s related starter projects make creating a Spring application possible with just a few lines of code. With Spring Boot recently hitting it’s 1.0 release, and Spring 4 having just been released in December, it’s an exciting time to get reacquainted with an old stand-by framework and tool set. The Getting Started projects at Spring.io serve their purpose extremely well, but as they are only intended to get a project up and running, they leave much to be discovered. The individual tutorials are great, but I had a hard time finding something that put it all together into an app similar to what would be required in the real world. I’ve recently started a new project using Spring Boot and Spring 4 and hope to share some of my experiences to date in a series of posts.

Here are the topics I hope to cover in each part:

Part 1: Getting Started (again): Build A Web App With Spring Boot
Part 2: Adding Views Using Thymeleaf
Part 3: Form Binding
Part 4: Locale Support
Part 5: Spring Security

As a reviewer…

One of the other things I spent time on last year was acting as a reviewer for a book that was recently published by Packt Publishing. I was approached by Packt early in the summer to volunteer to help review a work in progress called Enterprise Application Development with Spring and ExtJs. I was skeptical at first, so I did some research. Easily the majority of blog and message board content on the subject of being an unpaid reviewer, especially for Packt for some reason, was negative. This was an obvious red flag. However, I read a fair number of technical books, and I do enjoy writing, so I thought it might be an interesting thing to participate in, especially if I ever wanted to be an author in the future. In the back of my head I knew that if it became too much, especially given that it was volunteer time, that I could simply back out. I agreed to participate and off we went.

Here’s the basic deal: you get a couple of chapters to go through every 4 days. They give you a questionnaire to fill out with your comments. The publisher encourages feedback on many different levels – sentence structure and grammar, chapter-level organization and content, even the order of the chapters and higher level things. All fairly reasonable.

In all, I didn’t have a problem with the process. It was very interesting to see a book as a work in progress. By the time I was involved, it was clear the tools, table of contents and topics covered were fairly well set. Obviously, getting paid would have been nice, but I knew I was volunteering (well, I was getting a free ebook). I also knew the subject matter, which made things much easier. I was able to bypass the learning part of reading the book and focus on the content, how it was organized, and what type of an experience a reader would have with it.

On the book itself – it’s not bad, it’s just presented in a way that would be hard for me, personally, to digest. For a topic like this, I like to start with a clear goal – working through a project to learn a new technology. Additionally, I prefer consuming new information in small pieces and repeating that consumption, reinforcing foundational concepts while slowly increasing complexity, all the while verifying my progress with test cases. Some examples of books written in this fashion that I enjoyed: Agile Web Development with Rails, Grails in Action. This book is presented in a very waterfall-ish way in the name of Enterprise Application Development, and I think this is where I had the hardest time. Developing apps in the Enterprise does not require big up-front design or a waterfall development methodology. The reader is consuming huge new pieces of knowledge in each chapter, and we’re not doing anything to verify them as we go. The book has the reader waiting for a few layers of the application to be developed before performing integration tests. My concern here is that a reader will be trying to troubleshoot something they wrote two chapters ago, and that they just learned within the last few hours. That sounds frustrating!

Side note: I wasn’t a huge fan of the tools used in the book either. I feel like they are complex enough to be a distraction, that there are more modern/simple choices (Ivy, Eclipse, Spring Data) that would have possibly let the reader focus more on learning Spring and ExtJs.

In short, it was a great experience, I’m glad I did it, and I learned a lot, but if I ever do this again, I’ll make sure my own views and development/learning style are in better alignment with the author’s goals for the book.

RESTful Spring MVC and ExtJs (Episode 2, The ExtJs Stuff)

In the last post we talked about configuring Spring MVC for use as a RESTful API with the intention of using ExtJs for the UI work. In this post, I’ll review the ExtJs configuration work and highlight some of the important aspects of the project. I’ve included an example interface that will work with our previously configured back end. This app will be called ‘Gizmo Manager’. It will exercise the ExtJs MVC components and their RESTful proxies. Again, all of the source for this is on Github, for you to follow along with. On with it!

Installing ExtJs
There are two flavors of ExtJs – the open source version and the commercial version. For this project, I’m using the open source version (obviously)- 4.1.1 – you’ll notice I don’t have it checked in. The download(s) are available from Sencha, and although I haven’t used it, there is a copy on the Sencha CDN here. For this example, I’ve downloaded it and dropped it into my web project’s ‘js’ folder.
ExtJs install

Configuring ExtJs
To get the foundation for our app created, we’ll want to update our index.html file to reference both the ExtJs distribution, and our app (which will soon be created). Here’s what mine looks like when I’m done:

<html>
  <head>
    <title>Gizmo Manager</title>
    <link rel="stylesheet" type="text/css" href="js/extjs/resources/css/ext-neptune-debug.css">
    <script type="text/javascript" src="js/extjs/ext-all-debug.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body></body>
</html>

You’ll notice we’ve added two items related to our home page – a path to ExtJs itself (ext-all-debug.js), and a stylesheet reference. There are already-minified versions of ExtJs available in the distro, but for this example, I’m using the debug version as it is easier to troubleshoot configuration problems using it. As for the stylesheet, Neptune is one of the few themes that ExtJs comes packed with. They each have drawbacks, but I think Neptune has the most modern look and feel.

Next we’ll create our application’s folder structure. You’ll notice in the screenshot above a folder named ‘app’ and a file named ‘app.js’. These are both located in the /web/js folder, right alongside my extjs install. Our app.js file contains our application’s bootstrap information. This is how it looks:

Ext.application({
    name: 'gizmoManager',
    appFolder: 'js/app',
    controllers: ['GizmoController'],
    launch: function() {
        Ext.create('gizmoManager.view.MainViewport');
    }
});

You’ll notice some important items in this file. This is where we name our app and let ExtJs know where the source is located. We also give ExtJs a list of controllers to set up, as well as a view to create on launch. In this example, we’re using the MVC capabilities of ExtJs, so if you’re familiar with any other MVC framework, this should be easy to follow along with, at least structurally.

Our app directory has four folders in it – one each for controllers, models, views, and stores – all layers of the ExtJs flavor of MVC.
folders

Creating the Application
Let’s follow the ExtJs stack from front to back. Remember the default view we added to our app.js file? This is where our applications view components will be displayed. If we had multiple views in our app, our default view might be a card layout or a tab panel, where multiple views could be managed. In our app, we’ll configure a single view – more on that shortly. Here is our default view, the MainViewport.js, with it’s reference to our app’s single view component.

Ext.define('gizmoManager.view.MainViewport', {
    extend : 'Ext.container.Viewport',
    alias : 'widget.mainViewport',
    requires: [
        'gizmoManager.view.MainContainer'
    ],
    items : [{
        xtype : 'mainContainer'
    }]
});

In this file, you’ll notice two references to our app’s single view component – once in a parameter called ‘requires’ and once in a parameter called ‘items’. Think of items listed in the ‘requires’ parameter to ‘imported’ (in java terms) in to this file. Items in the ‘items’ parameter are displayed items, in the order they appear in the ‘items’ array.

The View
Since our ‘MainContainer’ is our application’s single view file, and our goal is exercise all of the RESTful API we created in our last post, you may think that it’s going to be very complicated. It’s really not! Adapting the gridpanel example from ExtJs docs, we’ll have an editable grid, which we can use to add, remove, update ‘Gizmos’. This file is called MainContainer.js, and is located in the root of the ‘view’ directory, along with MainViewPort.js. Our MainContainer.js file looks like this:

Ext.define('gizmoManager.view.MainContainer', {
    extend: 'Ext.tab.Panel',
    alias: 'widget.mainContainer',
    title: 'Gizmo Manager',
    items:[
        {
            xtype: 'gridpanel',
            title: 'Gizmos',
            store: 'Gizmo',
            name: 'editableGrid',
            columns: [
                {text: 'ID', dataIndex: 'id', width: 300},
                {text: 'DESCRIPTION', dataIndex: 'description', width: 300,
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }}
            ],
            columnLines: true,
            selModel: 'rowmodel',
            plugins: [
                Ext.create('Ext.grid.plugin.RowEditing', {
                    clicksToEdit: 1
                })
            ],
            dockedItems: [{
                xtype: 'toolbar',
                items: [{
                    action: 'add',
                    text:'Add Something'
                },'-',{
                    action: 'remove',
                    text:'Remove Something',
                    disabled: true
                }]
            }],

            width: 600,
            height: 300
        }
    ]
});

You can see we create our grid and add columns to display Gizmo data, we have added the row editing plugin for our grid panel (more info in the ExtJs docs on those topics), and we have also added a couple of buttons to the grid’s toolbar – one to remove items and another to add them. The buttons, the grid itself, and the rest of this don’t do much without the rest of the stack.

The Controller
The controller wires the stack together, serving as the middle man between the view and store/model, just as it would in any other MVC framework. We’ll named it GizmoController.js, and put it in our ExtJs app’s ‘controller’ folder. The controller’s main function in this example is listening to view events and interacting with our store/model. Overall, this is a pretty basic example, but again, exercises our whole API.

Ext.define('gizmoManager.controller.GizmoController', {
    extend: 'Ext.app.Controller',
    stores: ['Gizmo'],
    views: ['MainContainer'],

    refs:[
        {
            ref: 'mainContainer',
            selector: 'mainContainer'
        },
        {
            ref: 'editableGrid',
            selector: 'panel > gridpanel[name=editableGrid]'
        }
    ],

    init: function () {
        this.control({
            'mainContainer > gridpanel[name=editableGrid]' : {
                edit: function(editor, object) {
                    object.store.save();
                    object.store.commitChanges();
                },
                selectionchange: function(current, selections) {
                    this.getEditableGrid().down('button[action=remove]').setDisabled(selections.length == 0);
                }
            },
            'mainContainer > gridpanel > toolbar > button[action=add]' : {
                click: function(button) {
                    this.getGizmoStore().add(Ext.create('gizmoManager.model.Gizmo'));
                }
            },
            'mainContainer > gridpanel > toolbar > button[action=remove]' : {
                click: function(button) {
                    var selection = this.getEditableGrid().getSelectionModel(),
                        me = this;
                    Ext.each(selection.selected.items, function(gizmo) {
                        me.getGizmoStore().remove(gizmo);
                    });
                    me.getGizmoStore().sync();
                }
            }
        });
        this.getGizmoStore().load();
    }
});

In the ‘init’ property of the controller, we’ll see the four methods of our API as they exist in code. For the parameter-less GET (or ‘index’ in Grails/Rails terms), we use our GizmoStore’s load method. Our controller has a reference to the GizmoStore in it’s store array. This gives us an accessor to the store for free.

this.getGizmoStore().load();

For deletions, you can see the listener on the remove button’s click method:

'mainContainer > gridpanel > toolbar > button[action=remove]' : {
                click: function(button) {
                    var selection = this.getEditableGrid().getSelectionModel(),
                        me = this;
                    Ext.each(selection.selected.items, function(gizmo) {
                        me.getGizmoStore().remove(gizmo);
                    });
                    me.getGizmoStore().sync();
                }
            }

In this case, we’re using the control block, providing a path to the element we’d like to control (in this case, the delete button), and listening for the click method there. Again, you can see accessors available here – getting the editable grid – but this one is not free. In the controller, you’ll see the ‘refs’ parameter. The refs parameter allows us to define and name an array of objects for which we’d like accessor methods. In this case, we’ve got accessor for our view, and our view’s grid. Two other important things here: you can see the call to the GizmoStore’s remove button, followed by a call to the sync method.

The Model
The model (Gizmo.js) is stored in our app’s model folder. The model is used as a value object for the data going to and coming from our API. You’ll notice this is not a fat model like an ActiveRecord or a Model in Grails.

Ext.define('gizmoManager.model.Gizmo', {
    extend: 'Ext.data.Model',
    fields: ['id','description']
});

Not much more than the field config in our example, but more complex apps include validation information, proxy references, parent/child relationship configuration and much more. You can see the names of the fields in our model match with the ‘dataIndex’ parameters of the columns in our view. This is how our model is correctly bound to the grid.

The Store
The store is a singleton and maintains the client-side cache in ExtJs MVC applications. Our store contains a configured proxy through which the calls to our API are made. There are many convenient methods on the store for dealing with data in memory – comprehensions, finders, transformers, etc. In our example app, we’ll just be using the store for it’s proxy and synchronizing immediately after changes (see controller above).

Ext.define('gizmoManager.store.Gizmo', {
    extend: 'Ext.data.Store',
    model: 'gizmoManager.model.Gizmo',
    proxy: {
        type: 'rest',
        url : 'spring/gizmos',
        reader:{
            type: 'json',
            root: 'gizmos'
        }
    }
});

Above you can see our store’s configuration. The store contains a reference to the Gizmo model and a configured proxy. You’ll notice the proxy configuration points to our API, and is of the type ‘rest’. The ‘rest’ type proxy automatically makes calls to our API when we call methods like ‘load’ and ‘save’ and our store. Much more information in the ExtJs docs on that topic in the Ext.data.proxy.Rest class.

Run!
If you’ve been following along (or just skipped to downloading the project on Github), we should be able to run the app at this point. Here is what we should see:
Gizmo Manager
Click around and delete, edit, and add new Gizmos.

I hope this helped you get going faster than I did. Next up, design patterns in Scala!

RESTful Spring MVC and ExtJs (Episode 1, The Spring Stuff)

My latest adventures have taken me to a client replacing legacy Flex apps with ExtJs apps backed by Spring. In this two part post, you’ll see the product of the many bits of documentation, examples and blog posts I had to cobble together to get this set up, in hopes that it will serve as a complete example for someone else.

Background
If I had my druthers, I’d choose something a little more lightweight for the task at hand – at one time, this was supposed to be a Grails back end, and I was looking forward to getting back in to that mix. That option vaporized and we are now taking it a little slower with a Spring back-end. Thankfully, I work with folks that can make a little lemonade of that lemon, and we’re at least working with pretty close-to-the-latest core Spring, Spring MVC, Spring Data – version 3.2.1.

At the end of this post, you’ll have a working RESTful API provided by Spring using Spring MVC, and some of it’s new features. The source code is on Github so you can follow along. I will walk through the app’s configuration as well as the particulars of the controller class that will serve the front end.

Getting Started
We’ll start with the basic project layout and required jars:

ExtJs Project Layout

<ivy-module version="2.0">
    <info organisation="com.rodenbostel" module="SpringExtJs"/>
    <dependencies>
        <dependency org="org.springframework" name="spring-aop" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-beans" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-core" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-context" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-context-support" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-web" rev="3.2.1.RELEASE" />
        <dependency org="org.springframework" name="spring-webmvc" rev="3.2.1.RELEASE" />
        <dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.9.12" />
        <dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.9.12" />
        <dependency org="cglib" name="cglib-nodep" rev="2.2.2" />
    </dependencies>
</ivy-module>

Spring MVC Config
Spring 3.2 provides java-based Spring configuration (docs here). We’ll see a few examples of that here. The dispatcher servlet declaration and config remain in XML – all other bean declarations and config will be in java. First, in our web.xml file (/web/WEB-INF/web.xml), we need to configure the Spring MVC Dispatcher Servlet, as well as the Context Loader and it’s config locations. You can see a few important things here. The dispatcher servlet config itself, and it’s servlet mapping are near the bottom. They handle request routing, and will route requests behind “/spring/” to Spring MVC. We also see two context-params – the first (ContextClass) will tell Spring MVC to accept annotated classes as input in place of XML. The second (contextConfigLocation) will tell Spring MVC in which package to find the annotated classes that will make up the Spring config. Here is the web.xml in question:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.rodenbostel.springextjs.config</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

Next up is configuring the dispatcher servlet itself in dispatcher-servlet.xml. Not much to do here – we’re simply telling Spring MVC that we’ll be using annotations to drive our config. Note that by default, Spring MVC provides JSON request marshalling/unmarshalling using the given config (more on that later).

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- Enables the Spring MVC @Controller programming model -->
    <mvc:annotation-driven/>

</beans>

Moving On…
…to the interesting parts. We’ll start with the java based config. In this example, we’ll rely on component scanning and autowiring, and keep the config to a minimum. We’ll be scanning the ‘com.rodenbostel.springextjs’ package for more Spring Beans…

package com.rodenbostel.springextjs.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.rodenbostel.springextjs")
public class Config {
}

RESTful Controller
You can see the annotated controller below. There is quite a bit of config directly in the file, but from the start, you should notice that the class is marked with the controller interface annotation. Spring will recognize this during the context scan and make this a Spring bean. Next, we see five methods – one for each of the 4 familiar operations of CRUD, plus one that retrieves a single item for convenience sake, though still providing the same interface from the caller’s perspective. The 5 methods follow the paradigm used by scaffolded RESTful controllers created by Grails and Rails. In our app, the items the interface is being provided for are called ‘Gizmos’.

package com.rodenbostel.springextjs.controllers;

import com.rodenbostel.springextjs.viewmodel.Gizmo;
import com.rodenbostel.springextjs.viewmodel.ManyGizmoResponse;
import com.rodenbostel.springextjs.viewmodel.SingleGizmoResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

    @Controller
    public class ExampleGizmoController {

        @RequestMapping(value="/gizmos/{gizmoId}", method= RequestMethod.GET, produces=APPLICATION_JSON_VALUE)
        @ResponseBody
        public SingleGizmoResponse getFact(@PathVariable Long gizmoId) throws IOException {
            System.out.println("Gizmo retrieved.");
            return new SingleGizmoResponse(true,new Gizmo(1L,"HELLO"));
        }

        @RequestMapping(value="/gizmos", method= RequestMethod.GET, produces=APPLICATION_JSON_VALUE)
        @ResponseBody
        public ManyGizmoResponse getFacts() throws IOException {
            System.out.println("Gizmo search.");
            List<Gizmo> gizmos = new ArrayList<Gizmo>();
            gizmos.add(new Gizmo(1L, "HELLO"));
            gizmos.add(new Gizmo(2L, "WORLD"));
            return new ManyGizmoResponse(true,gizmos);
        }

        @RequestMapping(value="/gizmos", method= RequestMethod.POST, produces=APPLICATION_JSON_VALUE, consumes=APPLICATION_JSON_VALUE)
        @ResponseBody
        public SingleGizmoResponse createGizmo(@RequestBody Gizmo gizmo) throws IOException {
            System.out.println("Gizmo created.");
            return new SingleGizmoResponse(true,new Gizmo(1L,"NEW GIZMO"));
        }

        @RequestMapping(value="/gizmos/{gizmoId}", method= RequestMethod.PUT, produces=APPLICATION_JSON_VALUE, consumes=APPLICATION_JSON_VALUE)
        @ResponseBody
        public SingleGizmoResponse updateGizmo(@PathVariable Long gizmoId, @RequestBody Gizmo gizmo) throws IOException {
            System.out.println("Gizmo updated.");
            return new SingleGizmoResponse(true,new Gizmo(1L,"UPDATED GIZMO"));
        }

        @RequestMapping(value="/gizmos{gizmoId}", method= RequestMethod.DELETE, produces=APPLICATION_JSON_VALUE    )
        @ResponseBody
        public SingleGizmoResponse deleteGizmo(@PathVariable Long gizmoId) throws IOException {
            System.out.println("Gizmo deleted.");
            return new SingleGizmoResponse(true,new Gizmo(gizmoId,null));
        }
    }


For all of the methods, you’ll the ‘@RequestMapping’ annotation. This annotation is used by Spring for routing requests to individual controller methods. It also contains parameters that tell Spring what type data it can produce/consume and what HTTP verb the operation will be executed with. You’ll also see @RequestBody and @ResponseBody. Those tell Spring that the body of the request or response is to be unmarshalled and marshalled, respectively. By default (using the dispatcher-servlet config above), that format is JSON using the Jackson JSON utility. Let’s take a second to look at the value objects we’re mapping the aforementioned JSON to.

Here we have the Gizmo itself. You can see we’re using some annotations here to provide cues for the Jackson Utility. @JsonAutoDetect tells Jackson how to look at individual fields and which fields to look at. In our case, we’re telling Jackson to look only at those fields with a public accessor method.

package com.rodenbostel.springextjs.viewmodel;

import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonProperty;

import java.io.Serializable;

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.ANY, fieldVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.ANY)
public class Gizmo implements Serializable {
    private Long id;
    private String description;

    public Gizmo(){}

    public Gizmo(Long id, String description) {
        this.id = id;
        this.description = description;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Depending on the type of response we’re sending we’re also providing a class to wrap a single Gizmo, and multiple Gizmos. You can see in the source there we’re using the same annotations to instruct Jackson where to find the fields it needs to use.

package com.rodenbostel.springextjs.viewmodel;

import org.codehaus.jackson.annotate.JsonAutoDetect;

import java.io.Serializable;

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.ANY, fieldVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class SingleGizmoResponse implements Serializable {
    private boolean success;
    private Gizmo gizmo;

    public SingleGizmoResponse(boolean success, Gizmo gizmo) {
        this.success = success;
        this.gizmo = gizmo;
    }

    public boolean isSuccess() {
        return success;
    }

    public Gizmo getGizmo() {
        return gizmo;
    }
}


package com.rodenbostel.springextjs.viewmodel;

import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;

import java.io.Serializable;
import java.util.List;

@JsonAutoDetect(getterVisibility = Visibility.ANY, fieldVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class ManyGizmoResponse implements Serializable {
    private boolean success;
    private List<Gizmo> gizmos;

    public ManyGizmoResponse(boolean success, List<Gizmo> gizmos) {
        this.success = success;
        this.gizmos = gizmos;
    }

    public boolean isSuccess() {
        return success;
    }

    public List<Gizmo> getGizmos() {
        return gizmos;
    }
}

Our read methods are mapped to ‘GET’ at /gizmos. You’ll notice though, that the getFact method also takes a Path Variable using the @PathVariable annotation. Spring allows you to name path variables in your request mapping ({gizmoId} in this case) and bind them to parameters passed to the underlying method (@PathVariable Long gizmoId). Providing the path variable in the request mapping allows Spring to differentiate the two read methods – “/gizmos/1” will return a single gizmo whose id is 1, and “/gizmos” will return all of the gizmos in the database. Our write methods are mapped in much the same way, but you can see the difference in the HTTP methods they work with.

Fire up the app in your favorite container and head to /spring/gizmos, and experiment with the different calls. You can use a nice little Chrome app called Postman to make different types of calls to exercise the whole interface ahead of our ExtJs development.

Good luck and get ready for Part 2 where we add an ExtJs UI on top of what we’ve just developed!

SpringOne2GX, Day 2 Recap

Another good day at SpringOne.

The first session of the day was with Burt Beckwith going over the Spring Security plugin(s) for Grails. The last Grails work I did was with the Shiro/JSecurity plugin, which worked well, but I’ve always been interested in the extended feature set of Spring Security and it’s extensions. I thought the UI plugin looks useful, and the OpenID support looks like it’s got some nice features. Much of the rest still seems to be up in the air, but it’s maturing nicely. Glad to hear the demo code will be available.

Second talk was on the Google track, and was covering Spring Roo (which I promptly got stoked about yesterday) and it’s integration with GWT. I understand all of the browser compatibility advantages of GWT, but I’m still not convinced the complexity is worth it. Thankfully, Spring Roo does what it does best when it comes to GWT – generates and tucks away your boiler plate code. I’m not as excited about GWT as I thought I would be.

Third talk was with Burt Beckwith again – this time about strategies for handling database migrations in Grails apps. This is an aspect of Rails that I think is far superior to Grails. I didn’t get much from this talk other than how to correctly use Liquibase, but it was good to hear that this is something is being addressed in the upcoming version of Grails.

Fourth talk was about Extreme Scaffolding with Jean Barmash. We saw demos of a few interesting plugins for scaffolding and other UI enhancements, but I didn’t see anything really groundbreaking. It seems that a good command of grails templates, layouts and keeping DRY in mind would accomplish the same thing. It might even take longer to put all of these plugins in, and learn how to correctly use them, rather than just focus on writing good code and pushing out useful functionality.

Finishing the day with Stefan Schmidt and another great talk on the versatile persistence functionality available in the latest version of Spring Roo. The incremental reverse engineering is awesome and blows hibernate right out of the water. Grails and Rails are great for greenfield development, but this really makes Roo a compelling solution for developing new apps on existing databases. The JPA2 and NoSQL support were interesting. The one part I didn’t get was the discussion on Hades. Hades is a Roo add-on that generates the DAOs that Roo is made to get rid of (or at least hide). Maybe I missed something – it sounded interesting – I just didn’t see how it fit with the rest of the features of Roo, other than code generation, of course.

In all, not as good a day as the first, but I learned some interesting things. Spring Roo really seems like an exciting alternative Grails, especially if you’re developing in a dynamic language resistent environment. Looking forward to tomorrow.

SpringOne2GX, Day 1 Recap

It was an interesting day today at SpringOne2GX. There were many interesting presentations – here’s some thoughts on the 5 I attended today:

Guillaume Laforge’s talk on Gaelyk first thing in the morning was very interesting. I’ve been casually following the Gaelyk project for a while and was happy to hear more about it from the project’s founder. It looks like a great toolkit to easily take advantage of all of the features of the Google App Engine using a familiar and concise language in Groovy. A nice departure from Grails, Gaelyk is packed with a lot of interesting options and flexibility being on the Google App Engine. Definitely worth checking out for lightweight web apps with simple persistence needs.

Arjen Poutsma’s talk on the new features of Spring-WS was interesting also – good to see the familiar patterns and usages of Spring MVC making their way into the integration side. I’m currently on a Spring 3 project, and I’m quite sure there’s a compelling reason to roll this in. Definitely looking forward to getting into the details.

The Spring Roo presentation by Rod Johnson was a real eye-opener and definitely renewed my interest in the static-typed side of the Spring ecosystem. Grails, for straight java – what a cool idea. Pseudo-dynamic, clean code with boilerplate code woven in using AspectJ ‘side files’. I can’t wait to fire this one up, although I’m skeptical about how well I will work with it outside of eclipse/STS, which is not my first choice in regards to an IDE. The scaffolded UIs look very impressive. Looking forward to learning more about Roo + GWT tomorrow.

Another interesting Groovy-related talk was by Guillaume Laforge and Paul King on building DSLs with Groovy. A few very cool tricks and what I’m sure will be useful strategies for building DSLs using Groovy.

Wrapped up the day checking on the Grails 1.3 update with Graeme Rocher. Definitely a lot of stuff coming up that will be useful as the framework continues to grow. The GORM implementations at tonight’s keynote were awesome. New dependency management will be nice and clear with the right amount of control.

Looking forward to tomorrow!