Part 5: Integrating Spring Security with Spring Boot Web

Spring Boot provides utilities for quick and easy setup of Spring Security via auto-configuration and Java-based configuration. The getting started guide is quick and easy leads through configuring an in-memory AuthenticationManager in just minutes. Going beyond these examples, this installation will quickly review the getting started guide provided at Spring.io, and conclude with the configuration of a datasource-backed AuthenticationManager that uses Spring Data JPA, and the MySQL database platform.

As usual, for this installment, I’ve created a copy of the code from Part 4 and created a new project called Part 5. It’s committed to Github, ready for cloning.

Updating Dependencies
To install Spring Security, we first need to update our gradle script to include a dependency on spring-boot-starter-security. Update build.gradle to include the following dependency as seen below.

/build.gradle:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.thymeleaf:thymeleaf-spring4:2.1.2.RELEASE")

    testCompile("junit:junit")
}

Following that, executing a build should pull in our new dependencies.

Creating The Security Configuration
Continuing to lift code from the Spring.io docs for review, below you’ll find the example of the base Java security configuration. We’ll review the important bits after the jump. We’ll create this in the same directory as our other configuration files:

/src/main/java/com.rodenbostel.sample/SecurityConfiguration.java:

package com.rodenbostel.sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests().anyRequest().authenticated();
        http
                .formLogin().failureUrl("/login?error")
                .defaultSuccessUrl("/")
                .loginPage("/login")
                .permitAll()
                .and()
                .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }
}

As usual, the @Configuration annotation lets Spring know that this file contains configuration information. The next two annotations (@EnableWebMvcSecurity and @EnableGlobalMethodSecurity(prePostEnabled=true)) setup the automatically-configured portions of our security scheme, provided by Spring-Boot. EnableWebMvcSecurity basically pulls in the default SpringSecurity/SpringMVC integration. It’s an extension of the WebMvcConfigurerAdapter, and adds methods for handling and generating CSRF tokens and resolving the logged in user, and configures default AuthenticationManagers and Pre/Post object authorization implementations. The @EnableGlobalMethodSecurity sets up processors for authorization advice that can be added around methods and classes. This authorization advice lets a developer write Spring EL that inspects input parameters and return types.

Our SecurityConfiguration class also extends WebSecurityConfigurerAdapter. In Spring/Spring Boot, Configurer Adapters are classes that construct default bean configurations and contain empty methods which are meant to be overridden. Overriding these methods allow a developer to customize the Web Security Configuration during startup. Typically, the default configurations are constructed, and immediately following, the empty methods are called. If you’ve overridden an empty method, you’re able to inject custom behavior into the default configuration during the startup of the container.

In our case, the two coded parts of our SecurityConfiguration class (two methods named “configure”) are examples of these empty methods meant to be overridden. During container startup, after the HttpSecurity object’s default configuration is specified, our overridden method is called. Here we are able to customize the default configuration by specifying which requests to authorize, and how to route various security-related requests: default success URL, error routing, where to send logouts, etc. Also during container startup, after the AuthenticationManagerBuilder is configured, our configure method is called, and in this case we’re altering the default configuration, giving instructions to the AuthenticationManagerBuilder to build an in-memory AuthenticationManager with a default user credential and role.

You’ll notice in this configuration we’ve specified several URL paths that do not exist. There’s no login page or controller, and no way for a user to interact with the security configuration when the app is started up. Next, we’ll need to construct and wire in a login page to complete our beginning configuration.

Building The Login Page
The login page in the Spring.io sample is very straightforward. Just a simple form with an input for username and password. Let’s build that and review a few key parts.

/src/main/resources/templates/login.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
    <title>Spring Security Example</title>
</head>
<body>
<div th:if="${param.error}">
    Invalid username and password.
</div>
<div th:if="${param.logout}">
    You have been logged out.
</div>
<form th:action="@{/login}" method="post">
    <div><label> User Name : <input type="text" name="username"/> </label></div>
    <div><label> Password: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>

Most importantly, we have inputs with the names of “username” and “password”. These are the Spring Security defaults. If you’re routing a request to Spring Security to authenticate, these are the parameters on the request that it will be looking for. Next, you’ll also notice that there are Thymeleaf conditionals (th:if) for displaying logout and error messages if they are present in the response parameters during rendering. You’ll also notice the path to this page is “/login”, and the action on this form routes back to “/login” – but we don’t have those registered anywhere…

Registering the Login Action
The path our login form is posting to is the default used by Spring Security. This is where what used to be called the “j_spring_security_check” servlet is listening for requests to authenticate. The request path (where we’re retrieving the login form by issuing a GET to /login) is normally mapped to a controller, but in this case, since we’re using automatically configured features of Spring Boot, we need to specify this mapping in our application configuration. Add the code below to your application configuration. You may notice the use of another @Override method – another hook where we can add logic to customize our application…

/src/main/java/com.rodenbostel.sample.Application.java:

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }

Log In!
Start your server, and try to access the app again. For me, that’s simply visiting http://localhost:8080.

Screen Shot 2014-05-30 at 4.59.05 PM

I’m immediately challenged.

If I put in an invalid username or password, we should see an error:

Screen Shot 2014-05-30 at 4.59.27 PM

If I put in the correct credentials (id: user/password: password), we should be able to log in:

Screen Shot 2014-05-30 at 5.00.33 PM

Screen Shot 2014-05-30 at 5.00.38 PM

There’s quite a bit missing here still – let’s take this example a bit further – we’ll wire in components that would make this configuration closer to production ready – an AuthenticationManager backed by JDBC, configurable password encoders, and a UserDetailsService implementation that we can use to manage users.

Beyond The Examples
To begin taking steps closer to this solution being production-ready, we first need to back our app with a database. I’ll be using MySQL. I’ll assume you’ve got it installed and running (if you’re on a mac, I’d use Homebrew to accomplish that.

First, we’ll add the MySQL dependency to our gradle script:

/build.gradle:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.thymeleaf:thymeleaf-spring4:2.1.2.RELEASE")
    runtime('mysql:mysql-connector-java:5.1.6')

    testCompile("junit:junit")
}

Configuring A Datasource
I’ll be calling my schema in MySQL “beyond-the-examples”. I’ll assume you’ve used the same name. Conveniently, Spring Boot Starter projects have an automatically configured property source path. This means that using a properties file for configuration data we’d like to externalize simply requires creating an “application.properties” file and putting it somewhere on the application’s classpath. We’ll create that file now, and add properties that we’ll use to set up our datasource.

/src/main/resources/application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/beyond-the-examples
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.jpa.hibernate.dialect= org.hibernate.dialect.MySQLInnoDBDialect
spring.jpa.generate-ddl=false

You can see I’m using the default configuration for MySQL. I wouldn’t recommend that for production.

Next, we’ll build references to these properties in our application’s configuration, so that we can use them to create a datasource bean that we can inject into our security configuration. Update the application configuration file to add these properties:

/src/main/java/com.rodenbostel.sample.Application.java:

    @Value("${spring.datasource.driverClassName}")
    private String databaseDriverClassName;

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Value("${spring.datasource.username}")
    private String databaseUsername;

    @Value("${spring.datasource.password}")
    private String databasePassword;

Next create a Datasource @Bean using these properties in the same file.

/src/main/java/com.rodenbostel.sample.Application.java:

    @Bean
    public DataSource datasource() {
        org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
        ds.setDriverClassName(databaseDriverClassName);
        ds.setUrl(datasourceUrl);
        ds.setUsername(databaseUsername);
        ds.setPassword(databasePassword);

        return ds;
    }

Now, we have a datasource configured that we can @Autowire into any of our Spring beans, configuration or otherwise.

Create the Spring Security Tables
The DDL from the Spring.io docs is for HSQLDB. It’s syntax is not compliant with MySQL. Shout out to this guy (http://springinpractice.com/2010/07/06/spring-security-database-schemas-for-mysql) for publishing the MySQL versions of the default Spring Security schema. If you’re using MySQL like me, use the DDL from that blog to create a “users” table and an “authorities” table, then thank him. Since we’ll be properly encoding our passwords, we may want to make that password column a bit wider. Here’s what I ran:

create table users (    username varchar(50) not null primary key,    password varchar(255) not null,    enabled boolean not null) engine = InnoDb;create table authorities (    username varchar(50) not null,    authority varchar(50) not null,    foreign key (username) references users (username),    unique index authorities_idx_1 (username, authority)) engine = InnoDb;

Building The New Configuration
To start using the new datasource in the security configuration, we first need to wire the datasource bean into our SecurityConfiguration class. Update your SecurityConfiguration file to instruct spring to @Autowire this bean:

/src/main/java/com.rodenbostel.sample.SecurityConfiguration.java:

    @Autowired
    private DataSource datasource;

Next, we’re going to make a few significant changes to our AuthenticationManagerBuilder configuration to reference this datasource and a few other things, which I’ll review after the code:

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
        userDetailsService.setDataSource(datasource);
        PasswordEncoder encoder = new BCryptPasswordEncoder();

        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
        auth.jdbcAuthentication().dataSource(datasource);

        if(!userDetailsService.userExists("user")) {
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            authorities.add(new SimpleGrantedAuthority("USER"));
            User userDetails = new User("user", encoder.encode("password"), authorities);

            userDetailsService.createUser(userDetails);
        }
    }


Prior to this, our AuthenticationManagerBuilder was configured on a single line - we were using an in-memory configuration, and creating a user directly on it.  Here, we’ll use the AuthenticationManagerBuilder to move from using:


auth.inMemoryAuthentication()

to using:

auth.jdbcAuthentication().dataSource(datasource);

Assuming there are already users in the database, believe it or not, that’s all we need to begin using the JDBC-backed AuthenticationManager. The requirement for creating new users and managing existing users is a foregone conclusion. In our case, we’d like to automatically configure a default user on app startup just like we were before. We can get a handle on the automatically configuration (by Spring Boot) UserDetailsService through our AuthenticationManagerBuilder at:

auth.getDefaultUserDetailsService();

…but that doesn’t quite do everything we need. On the first line of our updated AuthenticationManagerBuilder configuration method, you can see we’ve created a new instance of one of the provide implementations of UserDetailsService provided by Spring. If you don’t have a reason to customize how you manage users in your system, that is a perfectly suitable implementation, but there are things to consider. Please consult the API docs for more detail (http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/apidocs/org/springframework/security/provisioning/JdbcUserDetailsManager.html). After creating the new reference to the JdbcUserDetailsManager, we need to set a reference to our datasource on it. Following that, we add our encoder for storing our passwords securely, and then we use the JdbcUserDetailsManager’s built-in functionality to check to see if our test user exists, and create him if he doesn’t.

Testing Again
Running the application should yield no change in behavior when compared with what we saw earlier. This is desired. What we will see that’s different will be in our database. Startup the app using: "gradle bootRun", and using your favorite database management tool, query the database to see our newly create user and their encoded password:

Screen Shot 2014-05-30 at 5.44.38 PM

Conclusion
I cobbled the information in this post from many sources - some I’ve remembered and have mentioned, and others I have not. I hope putting this information in a single post helps whoever stumbles upon it! That concludes this series of Spring Boot posts, but during the time I’ve been writing these, I’ve come up with two more topics to touch on, mostly surrounding further securing your app (http://www.jasypt.org/) and easier maintenance of your database tables (http://flywaydb.org/). Check back soon!

Advertisements

Part 4: Internationalization in Spring Boot

One of the many features provided by Spring Boot’s automatic configuration is a ResourceBundleMessageSource. This is the foundation of the support for internationalization provided by Spring as part of Spring Boot. However, resolving the user’s current locale, and being able to switch locales on demand is a little trickier, and is something that I had a hard time finding a comprehensive example of. In this installment, we’ll cover how to set up a resource bundle for messages, how to name them to support locales, and finally, how to wire a LocaleResolver and LocaleChangeInterceptor into our test application so that we can implement and test Spring’s internationalization support.

As usual, for this installment, I’ve created a copy of the code from Part 3 and created a new project called Part 4. It’s committed to Github, ready for cloning.

The Resource Bundle
First, we’ll create a resource bundle with message files for English and Spanish in our sample application. When provided a locale, the auto-configured message source can dynamically look up a message file using a default base file name – for example, the default messages file will be named “messages.properties”, whereas the file for Spanish messages will be called “messages_es.properties”. Likewise, the file for English language messages will be “messages_en.properties”. Basically, the message source resolves the file name in which to look for message properties by concatenating Spring’s default base file name “messages”, with an underscore and the locale name. The default location for these files, as specified by the auto-configuration, is “/src/main/resources”.

Create two files in /src/main/resources: messages_en.properties, and messages_es.properties.

We’ll add a couple of messages to each file, and we’ll use them to change the labels on our sample application’s based on the client’s locale.

Update “/src/main/resources/messages_en.properties”, adding the following properties and values:

/src/main/resources/messages_en.properties:

field1 = Field 1
field2 = Field 2

and likewise, for our Spanish clients, update “src/main/resources/messages_es.properties” to include the Spanish versions of the same properties and values (note that I do not speak Spanish. I typed these names into Google Translate. I think they are accurate enough for this example)

/src/main/resources/messages_es.properties:

field1 = El Campo 1
field2 = El Campo 2

Updating The View Template
The view template will need to be updated with placeholders containing the keys that Thymeleaf can use to swap in values from our message files. We’ve seen usages of ${} and *{} in these tutorials. The next one we’ll use is #{}, which is the placeholder Thymeleaf uses to bind messages, and can be used to do general string manipulation within the view.

Update our view template to include two new placeholders such that:

/src/main/resources/hello.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta charset="UTF-8" />
    <title>HELLO</title>
</head>
<body>
<p th:text="${message}"></p>
<form id="gizmo-form" role="form" th:action="@{/save}" method="post" th:object="${gizmo}">
    <div>
        <label for="field1" th:text="#{field1}"></label>
        <input type="text" id="field1" name="field1" th:field="${gizmo.field1}"/>
    </div>
    <div>
        <label for="field2" th:text="#{field2}"></label>
        <input type="text" id="field2" name="field2" th:field="${gizmo.field2}"/>
    </div>
    <div>
        <ul>
            <li th:each="item, stat : *{children}" class="itemRow">
                <div>
                    <label th:for="${'childField1-'+stat.index}">Field 1</label>
                    <input type="text" class="form-control quantity" name="childField1"
                           th:field="*{children[__${stat.index}__].childField1}" th:id="${'childField1-'+stat.index}"/>

                    <label th:for="${'childField2-'+stat.index}">Field 2</label>
                    <input type="text" class="form-control quantity" name="childField2"
                           th:field="*{children[__${stat.index}__].childField2}" th:id="${'childField2-'+stat.index}"/>
                </div>
            </li>
        </ul>
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
</form>
</body>
</html>

You can see we’ve removed the label text (formerly “Field 1” and “Field 2″ for the ‘field1’ and ‘field2’ properties on the Gizmo object and added new th:text references containing our new binding types. In these cases, our goal will be to replace #{field1} with the value of the “field1” property in the appropriate messages file, and to replace the value of #{field2} in a similar fashion. If you were to start the server at this point, the solution would still not work. The last step ties the views to the message files.

Configuring The LocaleResolver
In order for Spring to know which message file’s values to make available to Thymeleaf, the application needs to be able to determine which locale the application is currently running in. For this, we need to configure a LocaleResolver.

In ‘src/main/java/com.rodenbostel.sample.Application.java’ file, configure a new LocaleResolver bean.

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }

This will configure a locale resolver that fits the following description, according to the Spring API:

“Implementation of LocaleResolver that uses a locale attribute in the user’s session in case of a custom setting, with a fallback to the specified default locale or the request’s accept-header locale”

The only item remaining is how to switch the locale without updating the configuration of the bean above and restarting our server or changing our default or accept-header specified locale.

Configuring a LocaleChangeInterceptor
Configuring an interceptor that is responsible or swapping out the current locale allows for easy testing by a developer, and also gives you the option of including a select list in your UI that lets the user pick the locale they prefer. Add the following bean to your ‘src/main/java/com.rodenbostel.sample.Application.java’ file:

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

As you can see, this interceptor will look for a request parameter named ‘lang’ and will use its value to determine which locale to switch to. For example, adding ‘lang=en’ to the end of any request will render the messages from default English locale’s message file. Changing that parameter to ‘lang=es’ will render the Spanish version. For any interceptor to take effect, we need to add it to the application’s interceptor registry. In order to do that, we need to get a handle and override Spring Boot Web’s addInterceptor configuration method.

In order to do that, we need to update our ‘src/main/java/com.rodenbostel.sample.WebApplication.java’ file to extend WebMvcConfigurerAdapter. The WebMvcConfigurerAdapter’s existence is based on around activities such as this. It provides hooks to override base Spring configuration. Let’s update the class to extend this super class and add our interceptor:

package com.rodenbostel.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends WebMvcConfigurerAdapter {

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

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

}

Testing
Start your server and observe the default locale in action:
Screen Shot 2014-05-13 at 5.20.00 PM
then, add our request parameter and refresh the page to change the locale so that our Spanish language file is loaded:
Screen Shot 2014-05-13 at 5.20.52 PM
As Spring Boot matures, I’m sure the available examples will be updated to include end to end samples such as this. In the mean time, I hope you found this simple example useful. Check back soon for Spring Security integration in Part 5.

Part 3: Form Binding

Welcome back. Now that we have Thymeleaf view templates rendering in our Spring Boot test app, the next logical topic is learning how to bind java objects to forms in these views for processing. In this installment, we’ll cover binding a simple object to a form and then take a step deeper and bind an object with a list of children to a form. These are basic examples, but should show enough to get you started in most cases, and should be step beyond what’s available in the examples from Thymeleaf and Spring.

As usual, for this installment, I’ve created a copy of the code from part 2 and created a new project called Part 3. It’s committed to Github, ready for cloning.

The Gizmo
To get started, we’ll create a simple object that will eventually back a form in our app. We’ll call it gizmo, and we’ll give it two String fields with accessors and mutators.

/src/main/java/com.rodenbostel.sample.Gizmo.java:

package com.rodenbostel.sample;

public class Gizmo {

    private String field1;
    private String field2;

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public String getField2() {
        return field2;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }
}

Passing Gizmo To The View
Next, we’ll make a small change to our SampleController that will allow us to pass a gizmo instance to the browser in place of our previous message.

For this, change the previous version:

src/main/java/com.rodenbostel.sample.SampleController.java:

    @RequestMapping("/")
    public String index(Model model) {
        model.addAttribute("message", "HELLO!");
        return "hello";
    }

to this:

    @RequestMapping("/")
    public String index(Model model) {
        model.addAttribute("gizmo", new Gizmo());
        return "hello";
    }

Updating The View
Next, in place of displaying static text, we’ll update our view template so that it contains a form to which we can bind the instance of Gizmo. I’ll walk through the important bits after the code sample.

src/main/resources/hello.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta charset="UTF-8" />
    <title>HELLO</title>
</head>
<body>
<form id="gizmo-form" role="form" th:action="@{/save}" method="post" th:object="${gizmo}">
    <div>
        <label for="field1">Field 1</label>
        <input type="text" id="field1" name="field1" th:field="${gizmo.field1}"/>
    </div>
    <div>
        <label for="field2">Field 2</label>
        <input type="text" id="field2" name="field2" th:field="${gizmo.field2}"/>
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
</form>
</body>
</html>

Notice we’ve create a form and dropped in two “th” attributes – action and object. The th:action attribute signifies to what path the form’s contents will be submitted, and th:object tells Thymeleaf where to find the object to be bound in the response parameters – in our case, in the Model we’re returning with every controller method call.

Also notice the body of the form – we’re using the th:field attribute on the input elements we’ve created. This tells Thymeleaf which fields on the th:object to bind to these inputs.

Last, you may have realized that we haven’t create a method in our controller with an @ResponseMapping that will wire to the th:action we’ve specified… We need somewhere to post this form to.

Adding The Controller Method
Add a new method to your SampleController that will respond to a post issued from our new form

/src/main/java/com.rodenbostel.SampleController:

    @RequestMapping("/save")
    public String save(Gizmo gizmo) {
        System.out.println(gizmo.getField1());
        System.out.println(gizmo.getField2());
        return "hello";
    }

Notice that we don’t do anything special to bind the incoming request to our Gizmo model object on the server side. If the properties on the bound object match the request parameter structure, the request will bind automatically. Specialized binding can be accomplished using the @RequestParam annotation.

Also notice that we’re simply printing out the contents of the Gizmo object and rendering the same view again with the same form contents. Alternatively, you can issue a redirect to the “/“ path to clear the form, following the route that is
used when the app is started.

Instead of:

return “hello“;

redirect using:

return "redirect:/";

Start up your server to view the work we’ve done so far. You should see an empty form that looks similar to this:

Screen Shot 2014-05-12 at 5.25.52 PM

and when you complete the form and submit it, you should see output in your console similar to the following:
2014-05-12 17:26:50.780 INFO 23927 — [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet ‘dispatcherServlet’: initialization completed in 9 ms
hello
world

Binding Child Objects
A common use case involves binding child objects to the same form a parent object is bound to – items on an order, addresses on a user profile, etc. The syntax for accomplishing this in Thymeleaf is a bit messy, mostly due to the fact that this type of binding requires nested, escaped quotation marks to accomplish.

Let’s add a new object to the mix, one that will be the child of Gizmo.

/src/main/java/com.rodenbostel.sample.GizmoChild:

package com.rodenbostel.sample;

public class GizmoChild {
    private String childField1;
    private String childField2;

    public String getChildField1() {
        return childField1;
    }

    public void setChildField1(String childField1) {
        this.childField1 = childField1;
    }

    public String getChildField2() {
        return childField2;
    }

    public void setChildField2(String childField2) {
        this.childField2 = childField2;
    }
}

Another simple class with simple fields. Next, let’s add an iterable collection of these objects to the Gizmo object as a property.

/src/main/java/com.rodenbostel.Gizmo:

package com.rodenbostel.sample;

import java.util.ArrayList;
import java.util.List;

public class Gizmo {

    private String field1;
    private String field2;
    private List<GizmoChild> children;

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public String getField2() {
        return field2;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }

    public List<GizmoChild> getChildren() {
        if(children == null) {
            children = new ArrayList<GizmoChild>();
        }
        return children;
    }

    public void setChildren(List<GizmoChild> children) {
        this.children = children;
    }
}

Updating The View (again)
We’ll add a new section to our form so that we can iterate through the collection of GizmoChildren, creating a row of inputs for each element in the collection, and dynamically naming them so they bind correctly on the server side.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta charset="UTF-8" />
    <title>HELLO</title>
</head>
<body>
<form id="gizmo-form" role="form" th:action="@{/save}" method="post" th:object="${gizmo}">
    <div>
        <label for="field1">Field 1</label>
        <input type="text" id="field1" name="field1" th:field="${gizmo.field1}"/>
    </div>
    <div>
        <label for="field2">Field 2</label>
        <input type="text" id="field2" name="field2" th:field="${gizmo.field2}"/>
    </div>
    <div>
        <ul>
            <li th:each="item, stat : *{children}" class="itemRow">
                <div>
                    <label th:for="${'childField1-'+stat.index}">Field 1</label>
                    <input type="text" class="form-control quantity" name="childField1"
                           th:field="*{children[__${stat.index}__].childField1}" th:id="${'childField1-'+stat.index}"/>

                    <label th:for="${'childField2-'+stat.index}">Field 2</label>
                    <input type="text" class="form-control quantity" name="childField2"
                           th:field="*{children[__${stat.index}__].childField2}" th:id="${'childField2-'+stat.index}"/>
                </div>
            </li>
        </ul>
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
</form>
</body>
</html>

You can see the unordered list’s first child has a “th:each” attribute. That’s Thymeleaf’s comprehension mechanism for collections. The first two parameters – item and stat basically represent the current item in the collection and the state of the iterator at the time the element is being rendered. We can use this stat variable to get the index of the current item being displayed. We also see “*{children}”. This is slightly different from earlier examples and shows how Thymeleaf can scope binding to a parent object. In this case, our form is bound to gizmo, and we can reference it’s property named ‘children’ by using an asterisk instead of a dollar sign.

For each item in the collection, we’re creating two input fields with ids of childField1-[index] and childField2-[index]. You’ll also see the “th:field” attribute used again on these new inputs. In this case we’re building the binding names for these fields dynamically. It’s easiest explained by looking at the generated html.

Start your server and let’s look at the output.

The Rendered Product
You should see a form similar to the following after you start your server.

Screen Shot 2015-01-02 at 9.50.20 AM

And when we view the source for the same page, we should see something similar to this within our form:

<form id="gizmo-form" role="form" method="post" action="/save">
    <div>
        <label for="field1">Field 1</label>
        <input type="text" id="field1" name="field1" value="" />
    </div>
    <div>
        <label for="field2">Field 2</label>
        <input type="text" id="field2" name="field2" value="" />
    </div>
    <div>
        <ul>
            <li class="itemRow">
                <div>
                    <label for="childField1-0">Field 1</label>
                    <input type="text" class="form-control quantity" name="children[0].childField1" id="childField1-0" value="" />

                    <label for="childField2-0">Field 2</label>
                    <input type="text" class="form-control quantity" name="children[0].childField2" id="childField2-0" value="" />
                </div>
            </li>
        </ul>
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
</form>

You can see the names produced by Thymeleaf fit the standard Spring MVC compliant naming for child objects. They are identified uniquely as they would be an plain object notation.

Let’s update our controller to add a GizmoChild instance to our Gizmo on initial request, and print out our new child’s output on response:

/src/main/java/com.rodenbostel.sample.SampleController.java:

package com.rodenbostel.sample;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class SampleController {

    @RequestMapping("/")
    public String index(Model model) {
        Gizmo gizmo = new Gizmo();
        gizmo.getChildren().add(new GizmoChild());
        model.addAttribute("gizmo", gizmo);
        return "hello";
    }

    @RequestMapping("/save")
    public String save(Gizmo gizmo) {
        System.out.println(gizmo.getField1());
        System.out.println(gizmo.getField2());
        for(GizmoChild child : gizmo.getChildren()) {
            System.out.println(child.getChildField1());
            System.out.println(child.getChildField2());
        }
        return "redirect:/";
    }
}

As you can see, in our index method, we’re adding a child object to our Gizmo instance prior to adding to our model for display on the screen. Then, in the ‘save’ method, we’re looping through the collection of children and printing the output to our console. With our server running, by completing the form and submitting, we should see first our Gizmo’s properties, followed by the values for the fields on each child object.

Conclusion
Although this is a simplified example, this can easily be expanded to accommodate more complex use cases. Maybe you’re reading your Gizmos from a database, or maybe you need to create new Gizmos from scratch. The child collection needs to be instantiated for the Thymeleaf template to render correctly – it can be empty though. Having one child element in a collection in a new Gizmo object gives Thymeleaf a blank object to render. However, the fields Thymeleaf renders for that blank object could be created by jQuery (or another javascript library), and can be further added/removed from there.

Part 2: Adding Views Using Thymeleaf (and JSP if you want)

In Part 1 of this series, we set up a sample application using Spring Boot and some of it’s default configuration options. Now that we’ve got the shell of an application, we can start adding content to our application. By adding a single dependency to our project and using Spring Boot’s auto configuration settings, we get a free Thymeleaf configuration that’s ready to go.

For this installment, I’ve created a copy of the code from part 1 and created a new project. It’s committed to Github, ready for cloning.

Adding The Dependency

In the dependencies section of your build.gradle file, add the following entry:

compile("org.thymeleaf:thymeleaf-spring4:2.1.2.RELEASE”)

The end result should leave your build.gradle following looking like this:

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'
apply plugin: 'war'

jar {

    baseName = 'part-2'
    version =  '0.1.0'
}

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

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.thymeleaf:thymeleaf-spring4:2.1.2.RELEASE")

    testCompile("junit:junit")
}

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

Running a simple ‘gradle build’ from the CLI will install this new dependency.

Building On Part 1

At the conclusion of Part 1, we had a single controller in our project configured as a @RestController, which returned a simple string. To start using our new Thymeleaf installation, we need to create a view, and make minor changes to our controller.

The auto-configured Thymeleaf install looks for Thymeleaf templates to be available as resources on the classpath in a folder named ‘templates’.

Create a resources folder, and a folder named ‘templates’ within it, such that your project’s directory structure appears similar to the following:

Screen Shot 2014-04-15 at 9.51.50 PM

Creating A Template

Thymeleaf templates are intended to be natural – as close to straight HTML as possible, and easily interpreted by browsers and developers alike. Thymeleaf is packed with several dialects, and takes the place of JSP in the default stack provided by Spring.

Inside of our new templates folder (/src/main/resources/templates/), we need to create a new template that we’ll use as our first view. Create a file named “hello.html” that contains the following text:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta charset="UTF-8" />
    <title>HELLO</title>
</head>
<body>
<p th:text="${message}"></p>
</body>
</html>

There are two important parts of this simple example: First, in the html tag, you’ll see two new attributes that set up template to be processed by Thymeleaf. This will give the page access to use the family of “th” attributes in html tags, thereby having access to the features available in the basic Thymeleaf dialect. Second, in the body of the page, there is a “p” tag with a simple “th” attribute. We’ll see the usage of this shortly.

Modifying The Controller

As previously mentioned, our @RestController must change to return a processed view template instead of a simple String, as it does now. First, open our existing controller class, SampleController.java, and change the marker interface from @RestController on it so that it reflects a simple controller (@Controller).

@Controller
public class SampleController {

In order to provide our Thymeleaf template with data to display, we need to change our method’s signature to accept a Model, which we can then begin to populate. Model is much like it was in previous versions of Spring MVC – an arbitrary collection of java objects that can be displayed and bound to views. The framework will provide our controller method with an instance of a Model object for us populate. Change the “index” method on the SampleController to have the following signature:

public String index(Model model) {

Next, we’ll populate the “message” attribute of the Model instance so that we can see our message in our newly created view. Update the SampleController to do just that:

@RequestMapping("/")
    public String index(Model model) {
        model.addAttribute("message", "HELLO!");
        return "hello";
    }

Start your server to see our new page in action.

Screen Shot 2014-04-15 at 10.53.53 PM

This is a very basic example, but you can see that the “${message}” element in our Thymeleaf template has been replaced by the element that we put in the attribute named “message” in our UI Model in our controller. Look at the page source to see the end result.

A Step Further

Let’s say you want to change the path to templates or revert to JSPs. The settings provided by Spring Boot can be easily overridden by configuring an InternalResourceViewResolver in our Application.java config file. In the example below, you can see a change to the template path as well as a change to the template technology being used.

@Bean        
    public InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }

Of course, if you’ve changed to JSP, you’ll also have to add the appropriate dependencies to your build.gradle file. Both of the dependencies in question are available with embedded Tomcat, so they’ll be ‘providedRuntime’ dependencies.

    providedRuntime("javax.servlet:jstl")
    providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")

Conclusion

Hopefully, this installment sheds additional light on the basic configuration of Thymeleaf and points you in the correct direction if you need to configure your application beyond what is provided out of the box by Spring Boot Web. Next up, we’ll review objecting binding and validation in Thymeleaf, getting deeper into the details of the Thymeleaf dialects and the functionality they provide. Again, find the complete source code for Part 2 on Github!

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!

Find the Grails in Spring MVC

As I mentioned earlier, I recently moved back to the Java world after a brief and enjoyable foray into Groovy & Grails. After a few minutes of becoming reacquainted with Spring MVC, I found myself wanting to make my Spring MVC app behave more like a Grails app. I’m lazy, what can I say?

The request mapping annotations are the obvious first piece to the puzzle. The second piece is using model attributes. The third is a bit of javascript to get some flexibility in the view. Here we go.

Obviously, the class marked with the ModelAttribute annotation can be an actual model object or a command object.

The controller will look something like this:

/**
 * A simple controller, use it to display and update values in the command object.
 * 
 * @author justin
 */
@Controller
public class SampleController {

	@RequestMapping("/action-to-display-page.do") 
    public ModelAndView displayYourPage() {
		//build your command object
		ModelOrCommandObject modelOrCommandObject = new ModelOrCommandObject();
		modelOrCommandObject.setMessage("Hello world.");
		
		//put your command object in the model map.
		ModelMap modelMap = new ModelMap();
		modelMap.addAttribute("modelOrCommandObject", modelOrCommandObject);
		
		//build your ModelAndView object.
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addAllObjects(modelMap);
		modelAndView.setViewName("some-page.jsp");
		
		return modelAndView;
	}
	
	/**
	 * One of the actions that your page is submits to.
	 * @param modelOrCommandObject
	 * @param result
	 * @param status
	 * @return
	 */
	@RequestMapping("/one-action-to-call.do") 
    public ModelAndView actionOne( 
                    @ModelAttribute("modelOrCommandObject") ModelOrCommandObject modelOrCommandObject, 
                    BindingResult result, 
                    SessionStatus status) {
		//do whatever you need to with your command or model object for this command
		modelOrCommandObject.getMessage();
		return new ModelAndView();
	}
	
	/**
	 * Another action that your page submits to.
	 * @param modelOrCommandObject
	 * @param result
	 * @param status
	 * @return
	 */
	@RequestMapping("/another-action-to-call.do") 
    public ModelAndView actionTwo( 
                    @ModelAttribute("modelOrCommandObject") ModelOrCommandObject modelOrCommandObject, 
                    BindingResult result, 
                    SessionStatus status) {
		//do whatever you need to with your command or model object.
		modelOrCommandObject.getMessage();
		return new ModelAndView();
	}
}

We’ll have the option in the view to map one action to the controller or multiple actions. Multiple actions is easy with a bit of javascript.

The jsp will contain code like this;

<form:form action="/myapp/one-action-to-call.do" method="POST" modelAttribute="command" method="POST">
<!– some form fields –>
<button onclick="this.form.action=’/myapp/one-action-to-call.do’;submit()">One action</button>
<button onclick="this.form.action=’/myapp/another-action-to-call.do’;submit()">Another action</button>
</form:form>

That’s been working well for me as a simple bridge between Spring MVC and *some* of the convenience and efficiency of grails.