1. Overview

In this quick tutorial, we’ll take a look at what it takes to create a simple Spring MVC project with the Kotlin language.

This article focuses on Spring MVC. Our article Spring Boot and Kotlin describes how to set up a Spring Boot application with Kotlin.

2. Maven

For the Maven configuration, we need to add the following Kotlin dependencies:

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jdk</artifactId>
    <version>1.8.22</version>
</dependency>

We also need to add the following Spring dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

To compile our code, we need to specify our source directory and configure the Kotlin Maven Plugin in the build section of our pom.xml:

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>1.8.22</version>
    <executions>
        <execution>
            <id>compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
        <execution>
            <id>test-compile</id>
            <phase>test-compile</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3. The Web Resources

By default, Spring Boot applied web configuration automatically. All we need to do is to place our web resources in the correct locations.

3.1. The Static Resources

The corresponding static resources, such as HTML, CSS, javascript, and image files, are located under the 4 paths, and Spring will look for them one by one in this order:

  • classpath:/META-INF/resources/
  • classpath:/resources/
  • classpath:/static/
  • classpath:/public/

Let’s create a file named index.html and place it under the src/main/resources/static directory:

<html>
    <head>Home</head>

    <body>
        <h1>This is the body of the index view</h1>
    </body>
</html>

After running the project, we can access the index page at http://localhost:8080/.

3.2. The Template Resources

We can integrate the following template engines with Spring Boot by simply adding a maven dependency:

We use Thymeleaf in our case by adding the following dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

The default location for the templates is classpath:/templates/. Now we create a file named welcom.html and put it under the src/main/resources/templates directory:

<html>
    <head>Welcome</head>

    <body>
        <h1>This is the body of the welcome view</h1>
    </body>
</html>

The resources under the templates directory are invisible by default. We will get a 404 error when we visit http://localhost:8080/welcome.html. We need to create a controller or add a view controller configuration for the welcome page. Here is how to config it with annotation configuration:

@Configuration
open class ApplicationWebConfig : WebMvcConfigurer {
    override fun addViewControllers(registry: ViewControllerRegistry) {
        registry.addViewController("/welcome").setViewName("welcome");
    }
}

After running the project, we can access the welcome page at http://localhost:8080/welcome.

4. Spring MVC Configuration Without Spring Boot

Before integrating Spring Boot into our application, we need to use either the Kotlin annotation configuration or an XML configuration. And we need to use the origin maven dependency for Thymeleaf:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.1.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring6</artifactId>
    <version>3.1.1.RELEASE</version>
</dependency>

4.1. Kotlin Configuration

The annotation configuration is pretty simple. We set up view controllers, the template resolver, and the template engine. Thereafter we can use them to configure the view resolver:

@EnableWebMvc
@Configuration
open class ApplicationWebConfig : WebMvcConfigurerAdapter(), ApplicationContextAware {

    private var applicationContext: ApplicationContext? = null

    override fun setApplicationContext(applicationContext: ApplicationContext?) {
        this.applicationContext = applicationContext
    }

    override fun addViewControllers(registry: ViewControllerRegistry?) {
        registry.addViewController("/welcome").setViewName("welcome");
    }

    @Bean
    open fun templateResolver(): SpringResourceTemplateResolver {
        return SpringResourceTemplateResolver()
          .apply { prefix = "/WEB-INF/view/" }
          .apply { suffix = ".html"}
          .apply { templateMode = TemplateMode.HTML }
          .apply { setApplicationContext(applicationContext) }
    }

    @Bean
    open fun templateEngine(): SpringTemplateEngine {
        return SpringTemplateEngine()
          .apply { setTemplateResolver(templateResolver()) }
    }

    @Bean
    open fun viewResolver(): ThymeleafViewResolver {
        return ThymeleafViewResolver()
          .apply { templateEngine = templateEngine() }
          .apply { order = 1 }
    }
}

Next, let’s create a ServletInitializer class. The class should extend AbstractAnnotationConfigDispatcherServletInitializer. This is a replacement for the traditional web.xml configuration:

class ApplicationWebInitializer: AbstractAnnotationConfigDispatcherServletInitializer() {

    override fun getRootConfigClasses(): Array<Class<*>>? {
        return null
    }

    override fun getServletMappings(): Array<String> {
        return arrayOf("/")
    }

    override fun getServletConfigClasses(): Array<Class<*>> {
        return arrayOf(ApplicationWebConfig::class.java)
    }
}

4.2. XML Configuration

The XML equivalent for the ApplicationWebConfig class is:

<beans xmlns="...">
    <context:component-scan base-package="com.baeldung.kotlin.mvc" />

    <mvc:view-controller path="/welcome.html" view-name="welcome"/>
    <mvc:annotation-driven />

    <bean id="templateResolver" 
      class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML" />
    </bean>

    <bean id="templateEngine"
          class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
    </bean>


    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="order" value="1" />
    </bean>

</beans>

In this case, we do have to specify the web.xml configuration as well:

<web-app xmlns=...>

    <display-name>Spring Kotlin MVC Application</display-name>

    <servlet>
        <servlet-name>spring-web-mvc</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-web-config.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-web-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

5. Conclusion

In this article, we add the Spring MVC support and create a simple HTML view based on the Spring Boot application with Kotlin.

The complete source code is available over on GitHub.

Comments are closed on this article!