Spring Boot JPA Kotlin

Spring Boot provides a ready made solution to working with Java Persistence API (JPA). The post discusses how to make a basic web application that reads and writes employees to a database. We can also count how many employees have a certain name. This will all be done using Spring’s JPA features and the Kotlin programming language.

Spring Boot provides us with a data source on its own with very little configuration. Of course, we are free to connect the application to remote databases as well. To get started, we need to fill out some properties in the application.properties file found in src/main/resources

application.properties

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.datasource.driver-class-name=org.hsqldb.jdbcDriver

The first property, spring.jpa.hibernate.ddl-auto=create-drop tells the application to scan for all classes annotated with @Entity and create database tables for us. The persistence provider does the work of generating database definition language (DDL) and creating our database schema for us.

The second property configures Hibernate to act as our persistence provider. This is required because JPA is a specification. It requires a 3rd party library (Hibernate, EclipseLink, etc) to actually implement the specification. Finally, we need to tell the application what JDBC driver to use. This should match our database. In this case, we are using HSQLDB so we load their JDBC driver.

Database Entity

We need to create one or more persistant objects that are mapped to the database. In this case, we only have 1, an Employee Class, that we are using to map to a database table.

//This class maps to a table in the database
//that will get created for us
@Entity
data class Employee(
       @field: Id @field: GeneratedValue var Id : Long = 0, //Primary Key
       var name : String = "", //Column
       var position : String = "") //Column

Kotlin provides data classes for these sort of situations. The first property is annotated with Id and serves as the Primary Key. The GeneratedValue annotation tells the persistence provider to generate primary key values for us. The other two properties, name and position, end up becoming columns in the database table. When persistence provider scans this class, it will issue the correct commands to the database and generate an employee table with an primary key columna and two VARCHAR columns. Each instance of the Employee class that we store will become a record in the table.

Automatic Repositories

Spring is capable of generating @Repository classes for use when working with JPA. These repositories come fully loaded with 18 methods that handle all of our CRUD (create, read, update, and delete) methods and provide container managed transactions. We can even create our own custom queries using a naming convention and Spring will infer what needs to be done.

However, before we can have Spring generate our repositories for us, we need to tell it to do so. That’s pretty easy because all we need is a small configuration class.

Config

@Configuration
//The next line tells Spring Generate our JPA Repositories
@EnableJpaRepositories(basePackages = arrayOf("com.stonesoupprogramming.jpa"))
class Config

The package passed to the @EnableJpaReposities tells Spring where to look for repository interfaces. In order to make a Repository for the Employee class, we only need to declare an interface that extends JpaRepository.

EmployeeRepository

//The Implementation for this class is generated
//by Spring Data!
interface EmployeeRepository : JpaRepository <Employee, Long>{

    //Define a custom query using Spring Data
    fun countByNameContainingIgnoringCase(name : String) : Long
}

At no point will we ever write an implementation for this interface. When Spring sees this interface, it will generate an implementation class that is fully loaded and ready for our application to use. Technically, this interface could be empty, but we do have one method countByNameContainingIgnoringCase(String). Let’s discuss it.

Spring JPA Repositories are capable of defining queries on our persiteted objects provided that we follow the proper naming convention. Let’s take apart countByNameContainingIgnoringCase and discuss what each part means.

  • count — We are defining a count query
  • ByName — The syntax here is By[Property]. Our Employee class has a Name property, so we write ByName. If we wanted to use Position instead, it would be ByPosition
  • ContainingIgnoringCase — This is the predicate of the query. We are looking for anything containing a string value (in this case) and we are ignoring the case.

So in the end countByNameContainingIgnoringCase defines a query that means what it says. We are going to get a count of all records where the name contains a certain name and the name is not case sensitive. Spring is able to parse this name and create the correct query for us.

Put it in Action!

I wrote an MVC application that demonstrates how to use these concepts in a web application. Here is the code for the controller.

@Controller
@RequestMapping("/")
class IndexController(@Autowired private val employeeRepository: EmployeeRepository) {

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doGet(model : Model) : String {
        model.apply {
            addAttribute("employee", Employee())
            addAttribute("showName", false)
            addAttribute("employees", employeeRepository.findAll().toList())
        }
        return "index"
    }

    @RequestMapping("/employee_save", method = arrayOf(RequestMethod.POST))
    fun doEmployeeSave(employee: Employee,
                       model : Model) : String {
        employeeRepository.save(employee)
        model.apply {
            addAttribute("employee", Employee())
            addAttribute("showName", false)
            addAttribute("employees", employeeRepository.findAll().toList())
        }
        return "index"
    }

    @RequestMapping("/employee_count", method = arrayOf(RequestMethod.POST))
    fun doEmployeeCount(@RequestParam("name") name : String,
                        model : Model) : String {
        val count = employeeRepository.countByNameContainingIgnoringCase(name)
        model.apply {
            addAttribute("employee", Employee())
            addAttribute("showName", true)
            addAttribute("count", "Number of employees having name $name: $count")
            addAttribute("employees", employeeRepository.findAll().toList())
        }
        return "index"
    }
}

Even though we never wrote an implementation for EmployeeRepository, we can safely inject an instance of EmployeeRepository into our controller class. From this point, we have an HTTP GET method and two POST methods. The doEmployeeSave calls employeeRepository.save() and saves the incoming Employee object to the database. It also calls employeeRepository.findAll() and sends all employee records back to the view.

The doEmployeeCount calls our custom employeeRepository.countByNameContainingIgnoringCase method and returns a count of how many employee records contain the given name. We can pass this number back to the view. Once again, we are using employeeRepository.findAll().

This is the HTML code that works with the IndexController class.
indexhtml1indexcontroller2

Conclusion

The JPA cababilities provided by Spring Boot make developing ORM applications a breeze and it’s worth while to leverage them. For one thing, we only have to write a fraction of the code that we might have to write otherwise, but we are also less likely to introduce bugs into the application because we can trust the implementation of the JPA Repository classes and the persistence provided SQL generating capabilities.

Here are some screen shots of the finished application.


You can download the code at my GitHub page here or visit the YouTube tutorial.

Advertisements

Kotlin Stream Image from Database

Many web applications allow users to store images for later. For example, you may want to allow users to upload a profile picture that gets displayed later on in the application. This post demonstrates how to upload an image to a web application and store the image in a database. Then we will see how to display that image in a browser.

PersistedImage

The key to storing an image in a database is to use @Lob annotation in JPA and make the datatype as a byte array. Here is an example class that stores byte array in the database.

@Entity
data class PersistedImage(@field: Id @field: GeneratedValue var id : Long = 0,
                          //The bytes field needs to be marked as @Lob for Large Object Binary
                          @field: Lob var bytes : ByteArray? = null,
                          var mime : String = ""){

    fun toStreamingURI() : String {
        //We need to encode the byte array into a base64 String for the browser
        val base64 = DatatypeConverter.printBase64Binary(bytes)

        //Now just return a data string. The Browser will know what to do with it
        return "data:$mime;base64,$base64"
    }

Kotlin has a ByteArray class. In Java you would use byte []. The effect is the same either way. When persistence provider scans this class, it will store the byte array as a Lob in the database. Nevertheless it’s not enough to simply store an image in the database. At some point in time, the user will most likely wish to see the image. That’s there the toStreamingURI() method comes in handy.

The first line uses DatatypeConverter to convert the byte array to a base64 string. Then we can append that string to “data:[mime];base64,[base 64]”. In our example, we use Kotlin’s String template feature to build such a String. We start with the data: followed by the mime (such as /img/png). Then we can add the base64 string created by DatatypeConverter. This string can get added to the src attribute of the html img tag as shown in the screen shot below.

base64string
The browser knows how to display this string as an image.

File Uploads

It’s worth while to discuss how files are upload in Spring. Spring has a MultipartFile class that can get mapped to the a file upload input tag in the form. Here is how it looks in the HTML code.
fileuploadform
There are a couple of things that are critical for this to work. First, we have to set our applications.properties file to allow large file uploads.

spring.http.multipart.max-file-size=25MB
spring.http.multipart.max-request-size=25MB

Next our form tag has to set the enctype attribute to “multipart/form-data”. Finally we have to keep track of the name attribute on our input tag so that we can map it to the server code. In our example, our input tag has it’s name attribute set to “image”.

On the server end, we use this code get an instance of MultipartFile.

@RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doPost(
            //Grab the uploaded image from the form
            @RequestPart("image") multiPartFile : MultipartFile,
               model : Model) : String {
        //Save the image file
        imageService.save(multiPartFile.toPersistedImage())
        model.addAttribute("images", imageService.loadAll())
        return "index"
    }

We annotate the multipartFile parameter with @RequestPart and pass to the annotation the same name attribute that we set on our input tag. At this point, the container will inject an instance of MultipartFile that represents the file that the user uploaded to the server. The MultipartFile class has two attributes that are critical to our purposes. First it has a byte array property that represents the bytes of the uploaded file and it has the file’s MIME.

We can use Kotlin’s extension functions to add a toPersistedImage() method on MutlipartFile.

fun MultipartFile.toPersistedImage() = PersistedImage(bytes = this.bytes, mime = this.contentType)

This method simply returns an instance of PersisitedImage that can get stored in the database. At this point, we can easily store and retrieve the image from the database.

Application

The demonstration application is a regular Spring MVC application written in Kotlin. You can refer to this post on an explanation on how this works. Here is the Kotlin code followed by the HTML code.

Kotlin Code

package com.stonesoupprogramming.streamimage

import org.hibernate.SessionFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Controller
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestPart
import org.springframework.web.multipart.MultipartFile
import javax.persistence.*
import javax.transaction.Transactional
import javax.xml.bind.DatatypeConverter

@SpringBootApplication
class StreamImageDbApplication

fun main(args: Array) {
    SpringApplication.run(StreamImageDbApplication::class.java, *args)
}

@Entity
data class PersistedImage(@field: Id @field: GeneratedValue var id : Long = 0,
                          //The bytes field needs to be marked as @Lob for Large Object Binary
                          @field: Lob var bytes : ByteArray? = null,
                          var mime : String = ""){

    fun toStreamingURI() : String {
        //We need to encode the byte array into a base64 String for the browser
        val base64 = DatatypeConverter.printBase64Binary(bytes)

        //Now just return a data string. The Browser will know what to do with it
        return "data:$mime;base64,$base64"
    }
}

//This is a Kotlin extension function that turns a MultipartFile into a PersistedImage
fun MultipartFile.toPersistedImage() = PersistedImage(bytes = this.bytes, mime = this.contentType)

@Configuration
class DataConfig {

    @Bean
    fun sessionFactory(@Autowired entityManagerFactory: EntityManagerFactory) :
             SessionFactory = entityManagerFactory.unwrap(SessionFactory::class.java)
}

@Repository
class ImageRepository(@Autowired private val sessionFactory: SessionFactory){

    fun save(persistedImage: PersistedImage) {
        sessionFactory.currentSession.saveOrUpdate(persistedImage)
    }

    fun loadAll() = sessionFactory.currentSession.createCriteria(PersistedImage::class.java).list() as List
}

@Transactional
@Service
class ImageService(@Autowired private val imageRepository: ImageRepository){

    fun save(persistedImage: PersistedImage) {
        imageRepository.save(persistedImage)
    }

    fun loadAll() = imageRepository.loadAll()
}

@Controller
@RequestMapping("/")
class IndexController(@Autowired private val imageService: ImageService){

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doGet(model : Model) : String {
        model.addAttribute("images", imageService.loadAll())
        return "index"
    }

    @RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doPost(
            //Grab the uploaded image from the form
            @RequestPart("image") multiPartFile : MultipartFile,
               model : Model) : String {
        //Save the image file
        imageService.save(multiPartFile.toPersistedImage())
        model.addAttribute("images", imageService.loadAll())
        return "index"
    }
}

application.properties

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.datasource.driver-class-name=org.hsqldb.jdbcDriver

spring.http.multipart.max-file-size=25MB
spring.http.multipart.max-request-size=25MB

index.html

streamimage

Conclusion

Spring and Kotlin make it easy to embed images in a database and display those images in a browser. The main take away is to define a byte array property as a Lob on persisted image and then convert it to a base64 String when you wish to display it. Here are some screen shots of the working application.


You can get the source code for this project at my GitHub here or watch the video tutorial on YouTube.

Kotlin Spring JDBC Template

It’s typical for many applications, including web applications, to read and write to a database. JDBC operations are significantly simplified when using Spring JdbcTemplates and Kotlin’s language features. For example, it’s easy to one line read and insert operations into a database. This post goes through a sample web application that inserts a user into a database table and then prints a list of all users stored in the database.

Interacting with the Database

Our first order of business is to create a database schema. This is the SQL script that we will use to generate our database.

DROP TABLE IF EXISTS USERS;

CREATE TABLE USERS (
  id INTEGER IDENTITY,
  first_name VARCHAR(50),
  last_name VARCHAR(50),
  email VARCHAR(50),
  phone VARCHAR(50),
)

Now we will define a database that maps to the information held in our database. Kotlin’s data classes are ideal for this sort of task.

//Define a data class that maps to both our
//form and database table
data class User(var firstName: String = "",
                var lastName: String = "",
                var email: String = "",
                var phone: String = "")

There isn’t anything special about our User class. It’s only job is to carry information from the view to the database and back from the database to the view. Now that we have a database table and a transfer object, we need to configure our datasource so that Spring can connect our application to our database. We will define a configuration class that will define some Spring beans for us.

@Configuration
class Configuration {

    //First configure a data source that
    //generates an embedded db
    @Bean(name = arrayOf("dataSource"))
    fun dataSource(): DataSource {

        //This will create a new embedded database and run the schema.sql script
        return EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addScript("schema.sql")
                .build()
    }

    //Create a JdbcTemplate Bean that connects to our database
    @Bean
    fun jdbcTemplate(@Qualifier("dataSource") dataSource: DataSource): JdbcTemplate {
        return JdbcTemplate(dataSource)
    }
}

The first bean, dataSource, returns an EmbeddedDatabaseBuilder object that does the work of creating an embedded database, setting it’s dialect, and running our schema.sql script to create the database definition. At this point, our database is fully ready when the build() method is called.

The next bean is a JdbcTemplate object. We create a bean definition for it so that we can inject instances of this object into our repository classes later on. The JdbcTemplate requires a DataSource object, which happens to point at our embedded database. Now let’s define a repository class that will actually work with our JdbcTemplate.

@Repository
class IndexRepository(@Autowired var jdbcTemplate: JdbcTemplate) {


    fun addUser(user: User) {
        //We can use SimpleJdbcInsert to insert a value into our table
        //The becomes super concise when combined with Kotlins apply and mapOf functions
        SimpleJdbcInsert(jdbcTemplate).withTableName("USERS").apply {
            setGeneratedKeyName("id")
            execute(
                    mapOf("first_name" to user.firstName,
                            "last_name" to user.lastName,
                            "email" to user.email,
                            "phone" to user.phone))
        }
    }

    //This allows us to query the Users table and return a list of users
    //This is one method call to jdbcTemplate with a lambda expression which makes the code
    //incredibly concise
    fun allUsers(): List = jdbcTemplate.query("SELECT FIRST_NAME, LAST_NAME, EMAIL, PHONE FROM USERS",
            { rs: ResultSet, _: Int ->
                User(rs.getString("first_name"), rs.getString("last_name"), rs.getString("email"), rs.getString("phone"))
            })
}

@Respository is a Spring sterotype annotation that marks our IndexRepository as a class that is intended to interact with the datasource. Spring provides two other stereotype annotations, @Controller and @Service, that are typically used to mark seperations in the application. @Controller is intended to interact with the view, while @Respository works with datasource. @Service should contain business logic. When developers follow this pattern, the application maintains loose coupling which makes it easy to maintain and test code.

Since IndexController is marked with @Repository, it makes sense to inject JdbcTemplate into this class so that it can work with the database. We have two methods in this class: addUser and allUsers. We’ll take each function on its own.

The addUser(user : User) method performs an insert into the database. We create an instance of SimpleJdbcInsert and pass our JdbcTemplate object into this class. The following call to withTable(“USERS”) specifies which table we are inserting a record into. Since our primary key is generated automatically by the database, we can use SimpleJdbcInsert.setGeneratedKeyName(“id”) to assign a primary key. Finally we use the execute() function to actually perform the insertion into the database. The execute() takes a map where the key is the name of the column in the database and the value is what we are inserting into the column.

There is some Kotlin magic that helps keep the code concise. For one, we are chaining our calls to setGeneratedKeyName() and execute() inside of the apply() function. We can also leverage Kotlin’s mapOf() function to generate a Map on the fly as opposed to creating a map object and populating it with values ahead of time.

The allUsers() function queries the database. In this case, we can call the query method from the jdbcTemplate object. The query() method requires two parameters. The first parameter is the query that is sent to the database. The second method is a an instance of RowMapper, which is a single abstract method (SAM) class. Since RowMapper has only one method, we can use a lambda expression to provide an implementation of RowMapper.

The RowMapper’s job is to transform the results of the database query into a User object. It provides with two objects that help with this job. The first is the good old JDBC ResetSet object and the other object is an Int that represents the row number. We only use the ResultSet in this example. The ResultSet interface has a getString() method that takes the name of the column and outputs the value stored in that column. Using getString(), we can populate each field of a User object and return it. RowMapper will handle the details of building a list and returning the List to the caller.

Web Portion

The remaining part of the application is a Spring MVC application. We aren’t going to spend a lot of time on this portion but are including it for After the @Repository tier (covered above), we have a service class that handles the business logic between the @Controller and the @Repository. In our case, it’s really boring because all our @Service class is doing is acting as a wrapper for our @Repository class, but in the real world, there is generally more application code located in this class.

@Service
class IndexService(
    //Inject IndexRepository here
    @Autowired var indexRepository: IndexRepository) {

    fun addUser(user: User) {
        indexRepository.addUser(user)
    }

    fun allUsers(): List {
        return indexRepository.allUsers()
    }
}

We also have a @Controller class that handles HTTP GET and POST requests.

@Controller
@RequestMapping("/")
class IndexController(@Autowired var indexService: IndexService) {

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doGet(model: Model): String {
        model.addAttribute("user", User())
        model.addAttribute("allUsers", indexService.allUsers())
        return "index"
    }

    @RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doPost(model: Model, user: User): String {
        indexService.addUser(user)

        model.addAttribute("user", User())
        model.addAttribute("allUsers", indexService.allUsers())
        return "index"
    }
}

And finally the view…
View

Conclusion

Kotlin greatly enchances the already excellent JDBC abilities offered by Spring Boot. As was demonstrated in this post, developers can start with definining a data class that holds all of the data in a single row in a database table. When it comes to actually perform inserts or queries from the database, Kotlin’s mapOf(), apply, and to functions cut down on any additional verbosity that might still remain from using JDBC Template. As always, Spring makes it super simple to spring up a web application that interfaces with a database.

You can grab the source for this example from my GitHub page or view the Video tutorial on YouTube.

Kotlin Spring Security Custom Login

Spring Security provides a custom login page that is functional but not very attractive. In most cases, web developers want a more attractive looking login page. This post demonstrates how to configure Spring Security to use a custom login page. Readers can view this tutorial for a demonstration on how to configure basic Spring Security.

Front End—Write a Custom Page

We are going to start by writing a custom login page. Spring Security is very flexible about the page itself, but there are a few rules that need to be followed.

  • Form requires Username
  • Form requires Password
  • CSRF Token is required

This is a screen shot of the page that will be used for this tutorial.
LoginPage
Followed by the code.
LoginCode
It’s critical to remember to include the CSRF token in the form. Without it, the server will refuse any HTTP POST requests and will respond with code 405. The th:name="${_csrf.parameterName}" th:value="${_csrf.token}" on an input take will do the job of adding the CSRF token.

Backend—Configure Spring

Once the front end code is ready, you need to configure Spring Security to use this page. In order to render the login page, Spring will need some sort of controller class. Developers are free to write their own, but it’s also trivial to make use of the one Spring is happy to provide.

@Configuration
class WebConfig : WebMvcConfigurerAdapter() {
    override fun addViewControllers(registry: ViewControllerRegistry) {
        //This class adds a default controller for the login page.
        //Otherwise you would need to write a custom controller class
        registry.addViewController("/login").setViewName("login")
    }
}

The next job is to configure Spring security.

@Configuration //Make this as a configuration class
@EnableWebSecurity //Turn on Web Security
class SecurityWebInitializer : WebSecurityConfigurerAdapter(){
    override fun configure(http: HttpSecurity) {
        http
                .authorizeRequests()
                    //We need to allow anonymous users to
                    //access the login page (otherwise we get 403)
                    .antMatchers("/login").anonymous()
                    .anyRequest().authenticated()
                .and()
                    //Setup a custom login page
                    .formLogin()
                        .loginPage("/login")
                        .usernameParameter("username")
                        .passwordParameter("password")
                .and()
                    .httpBasic()
    }

    override fun configure(auth: AuthenticationManagerBuilder) {
        //This code sets up a user store in memory. This is
        //useful for debugging and development
        auth
                .inMemoryAuthentication()
                    .withUser("bob")
                    .password("belcher")
                    .roles("USER")
                .and()
                    .withUser("admin")
                    .password("admin")
                    .roles("USER", "ADMIN")
    }
}

It’s important to allow anonymous() access to the login page. Without it, Spring Security will continue to redirect to the login page until the server returns 403 (too many redirects).

Conclusion

Once complete, the site will render a custom login page like what is shown in the video.

You can get the code for the complete project at my GitHub page.

Spring Security Form Login with JDBC – Kotlin

Spring Security makes it really simple to authenticate users against a database. This tutorial builds on the previous tutorial of configuring Spring Security to secure web applications.

Database Schema

Spring Security is happy to do all of the work of querying a database and validating user information provided your database conforms to the correct database schema (note, you are free to customize). Here is the sql script that is used to configure an example datasource for this project that is based of the one provided in the Spring documetation.

/* See https://docs.spring.io/spring-security/site/docs/current/reference/html/appendix-schema.html */

DROP TABLE IF EXISTS persistent_logins;
DROP TABLE IF EXISTS group_members;
DROP TABLE IF EXISTS group_authorities;
DROP TABLE IF EXISTS groups;
DROP TABLE IF EXISTS authorities;
DROP TABLE IF EXISTS users;

create table users(
  username varchar_ignorecase(50) not null primary key,
  password varchar_ignorecase(50) not null,
  enabled boolean not null
);

create table authorities (
  username varchar_ignorecase(50) not null,
  authority varchar_ignorecase(50) not null,
  constraint fk_authorities_users foreign key(username) references users(username)
);

create unique index ix_auth_username on authorities (username,authority);

create table groups (
  id bigint generated by default as identity(start with 0) primary key,
  group_name varchar_ignorecase(50) not null
);

create table group_authorities (
  group_id bigint not null,
  authority varchar(50) not null,
  constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);

create table group_members (
  id bigint generated by default as identity(start with 0) primary key,
  username varchar(50) not null,
  group_id bigint not null,
  constraint fk_group_members_group foreign key(group_id) references groups(id)
);

create table persistent_logins (
  username varchar(64) not null,
  series varchar(64) primary key,
  token varchar(64) not null,
  last_used timestamp not null
);

insert into users values('bob_belcher', 'burger_bob', true);
insert into authorities values ('bob_belcher', 'user');

This script drops all tables if they exist and then recreates the database tables. It also populates the database with a user: bob_belcher. Creating and destroying the DB in this fashion is useful for both development purposes and unit testing. Naturally, a production machine would preserve the data each time.

Spring Configuration

Configuring Spring Security to work with our database is a complete breeze at this point. We start by creating two bean definitions for both a data source and a jdbcTemplate.

@Configuration
class DataConfig {

    @Bean(name = arrayOf("dataSource"))
    fun dataSource() : DataSource {
        //This will create a new embedded database and run the schema.sql script
        return EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addScript("schema.sql")
                .build()
    }

    @Bean
    fun jdbcTemplate(@Qualifier("dataSource") dataSource: DataSource) : JdbcOperations {
        return JdbcTemplate(dataSource)
    }
}

Since I am using Spring Boot, I did qualify our dataSource bean so that the container knew which bean I wanted to use for our datasource.

Now that we have our data source configured, we just need to tell Spring Security about it. It’s not very difficult.

@Configuration //Make this as a configuration class
@EnableWebSecurity //Turn on Web Security
class SecurityWebInitializer(
        //Inject our datasource into this class for the AuthenticationManagerBuilder
        @Autowired @Qualifier("dataSource") val dataSource: DataSource)
    : WebSecurityConfigurerAdapter(){

    override fun configure(http: HttpSecurity) {
        http
                    .formLogin()
                .and()
                    .logout()
                        .logoutSuccessUrl("/")
                .and()
                    .rememberMe()
                        .tokenRepository(JdbcTokenRepositoryImpl())
                            .tokenValiditySeconds(2419200)
                                .key("BurgerBob")
                .and()
                    .httpBasic()
                .and()
                    .authorizeRequests()
                        .antMatchers("/").authenticated()
                        .anyRequest().permitAll()
    }

    override fun configure(auth: AuthenticationManagerBuilder) {
        //As long as our database schema conforms to the default queries
        //we can use jdbcAuthentication and pass in our data source
        //Spring will do the rest of the work for us
        auth.jdbcAuthentication().dataSource(dataSource)
    }
}

In this case, all that is needed is to call auth.jdbcAuthentication().dataSource and pass in our dataSource object. Spring Security takes it from there.

Conclusion

Here is a video of this in action.

You can grab the entire code from my Github page here.

Kotlin Spring Security Tutorial

Just about anybody can appreciate the value of securing a web application. After all, who would do their online banking on an unsecured website? Of course, it’s not just online banking that requires security. Just about any website that has information that requires protecting needs security.

Spring provides web security modules that help us secure our applications. As with everything in Spring, it’s really easy to use an configure.

Define a Security Class

Spring has us extend the WebSecurityConfigurerAdapter class and annotate it with @Configuration and @EnableWebSecurity. Here is an example Kotlin class that enables our web security and forces all requests to the web application to be authenticated.

@Configuration //Make this as a configuration class
@EnableWebSecurity //Turn on Web Security
class SecurityWebInitializer : WebSecurityConfigurerAdapter(){
    override fun configure(http: HttpSecurity) {
        //This tells Spring Security to authorize all requests
        //We use formLogin and httpBasic
        http
                .authorizeRequests()
                    .anyRequest()
                    .authenticated()
                .and()
                    .formLogin()
                .and()
                    .httpBasic()
    }

    override fun configure(auth: AuthenticationManagerBuilder) {
        //This code sets up a user store in memory. This is
        //useful for debugging and development
        auth
                .inMemoryAuthentication()
                    .withUser("bob")
                    .password("belcher")
                    .roles("USER")
                .and()
                    .withUser("admin")
                    .password("admin")
                    .roles("USER", "ADMIN")
    }
}

The first method, configure(http: HttpSecurity) calls methods on the http object. This class has a chaining interface and by calling the proper methods, we can tailor the security configuration to suit our needs. The methods are plain english, so the code ends up being highly self-documenting.

The other configure method accepts an auth: AuthenticationManagerBuild. The auth object is used to configure a data store for users. For the purposes of this post, we are creating an inMemoryAuthentication. This is useful for development and debugging purposes.

The Controller Class

There isn’t anything special about the controller class. That’s a feature of Spring Security. Security is a cross cutting concern which means that the main application code should not have to concern itself with security. Instead, Spring uses Aspect Orientated programming to secure our application.

Sometimes it’s useful to know what user is logged into this system. There is a an example of how to access this information and pass it back to the view. (Readers who are not familiar with Spring MVC can refer here for an example of Spring MVC).

@Controller
@RequestMapping("/")
class IndexController {

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doGet(model : Model) : String {
        //We can access the current user like this
        val authorization = SecurityContextHolder.getContext().authentication

        //Send the user name back to the view
        model.addAttribute("username", authorization.name)
        return "index"
    }
}

The SecurityContextHolder class provides an access point to the current logged in user. Spring calls it an authentication. The object returns contains information about the user such as the user name.

Conclusion

Here is a video of logging into this site in action.

You can get the code from my github page here.

Spring Bean Validation Example (JSR-303) in Kotlin

Many developers need a solution to validating forms. Spring MVC supports bean validation (JSR-303) which is an easy to use annotation driven framework that is used to validate objects. Spring utilizes bean validation throughout the entire application framework, allowing developers to annotation one or more objects and ensure they are valid from the controller all the way to the data access layer.

Since Kotlin is compatible with Java libraries, this post demonstrates how to use bean validation along with Spring MVC to validate a user registration form. Here is a screen shot of the form we are going to validate.
WelcomeScreen copy

Step 1—Define a Form Object

We will use a POJO that carries data from the view to the server. Kotlin makes this really easy because it provides data classes.

data class User(@get: NotBlank (message = "{first_name.required}")
                    var firstName : String = "",

                @get: NotBlank (message = "{last_name.required}")
                    var lastName : String = "",

                @get: NotBlank (message="{email.required}")
                @get: Email (message = "{email.invalid}")
                    var email : String = "",

                @get: NotBlank (message="{phone.required}")
                    var phone : String = "",

                @get: NotBlank (message="{address.required}")
                    var address : String = "",

                @get: NotBlank (message="{city.required}")
                    var city : String = "",

                @get: NotBlank (message="{state.required}")
                @get: Size(min=2, max=2, message = "{state.size}")
                    var state : String = "",

                @get: NotBlank (message="{zip.required}")
                    var zip : String = "")

You will notice a couple of things in the class. The first is the @get [annotation] annotation. Kotlin generates getter/setter methods in the Java bytecode. When we use the @get annotation followed by the annotation, Kotlin will place the target annotation on the getter method. So for example, @get: NotBlank is telling the Kotlin compiler to place the @NotBlank annotation on the generated getter method.

Next you will notice the message argument that is passed to the NotBlank annotation. In the first example, we have message = “{first_name.required}”. The message parameter takes a String that is displayed to the user when validation fails. If we use expression language, Spring boot will look for a ValidationMessages.properties file that contains the actual message. This is useful when making localized applications because you can have a different ValidationMessages file per language.

In this example, we are using three different Hibernate Validator annotations.

  • NotBlank—Valid if a String is not blank. Fails is the String is blank or null.
  • Email—Valid if the string field contains a valid email address
  • Size—Valid if the string has at least min number of characters and less than max characters

Step 2—ValidationMessages.properties

If you choose to use a ValidationMessages.properties file, Spring Boot will look for the actual message inside of a ValidationMessages.properties file in the applications classpath. I find this to be the preferred approach because it allows develoeprs to easily localize an application if needed. Here is the properties file we are using in this example.

first_name.required="First name is required"
last_name.required="Last name is required"
email.required="Please enter your email address"
email.invalid="Please provide a valid email address"
phone.required="Please enter a phone number"
address.required="Please enter your address"
city.required="Please enter a city"
state.required="Please enter a state"
state.size="Please use 2 letter state code"
zip.required="Enter a zip code"

The keys of the file are the same as when is passed to the message parameter of each bean validator annotation. The value is what is ultimately displayed to the user.

Step 3-Controller

Spring MVC uses a controller class. Here is the code for our controller in this example.

@Controller
@RequestMapping("/")
@Scope(WebApplicationContext.SCOPE_REQUEST)
class ValidatorController(@Autowired val registrationService: RegistrationService) {

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doGet(model : Model) : String {
        model.addAttribute("user", User())
        return "index"
    }

    @RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doPost(@Valid user : User,  //The @Valid annotation tells Spring to Validate this object
               errors : Errors)  //Spring injects this class into this method. It will hold any
                                //errors that are found on the object
            : String {
        val result : String
        when {
            //Test for errors
            errors.hasErrors() -> result = "index"
            else -> {
                //Otherwise proceed to the next page
                registrationService.user = user
                result = "redirect:/congrats"
            }
        }
        return result
    }
}

The first method is doGet which is mapped to an HTTP Get request. Nothing fancy here for those readers who are famailier with Spring MVC (This post explains Spring MVC for users who are not famalier with Spring MVC). All we do here is create a new instance of the User class and pass it to the view.

The doPost is the method that we care about for this post. This method has two parameters. The first one is a User argument that is annotated with @Valid. The other one is an Errors object. These two argument work in tandem to validate a Spring MVC form.

The User object is bound to the web form. Each field in the form is mapped to a property on the User class. When the form is submitted, Spring MVC carries this object from the View to the Controller. However, if the parameter has the @Valid annotation, then the User object make a stop and is examaned by a class that impelements javax.validation.Validator. Should the validation report any errors, they are gathered together in the Errors object that is injected into this method.

The errors.hasErrors() method returns true if the user entered invalid input into the form. We can return the name of the page that was submitted and report the errors back to the user if that is the case. Here is what it looks like.
Invalid copy

On the other hand, we can redirect the user to the next page if everything is ok (errors.hasErrors() == false).
Congrats copy

Step 4—The View

Of course, we need to setup our web page properly in order to actually see the errors. Since I am a big fan of Twitter’s Bootstrap, I use their form validation framework to make a nice front-end display to the errors message.

Here is a code snippet of a field on the form.
field
We use a teneray expression to check each field if it has errors th:class="${#fields.hasErrors('firstName') ?'form-group has-error' : 'form-group'}". If the field has an error, we use bootstraps has-error css class to get the red outline. Otherwise, we don’t add that class and just use form-group. In case you are wondering, the fields object is the same Errors object that we were using in our server code. This is just another rendition of the same object.

The next thing to do is print out each error. This can be done very easily by using the th:each tag and assigning each message to the err variable: th:each="err: ${#fields.errors('firstName')}" class="help-block" th:text="${err}". When executed, this code will look up the message (found in ValidationMessages.properties) for each error and write is out to a span tag.

When run, each field that has an error will have its textbox outlined and the error message printed below the text box.

Getting the Code

You can get the complete code for this project at my github page.

Result

Here is the final result