HelloKoding

Practical coding guides

Spring MVC Thymeleaf Example of XML Configuration

This tutorial walks you through the process of creating a Hello World example web site with Spring MVC XML Configurations and Thymeleaf

What you’ll build

Spring MVC XML Hello World

What you’ll need

  • Your favorite IDE
  • JDK 1.8+
  • Maven 3+

Stack

  • Spring MVC 5
  • Thymeleaf View Template

Init project structure and dependencies

Project structure

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── hellokoding
│       │           └── springmvc
│       │               └── HelloController.java
│       ├── resources
│       │   ├── application.properties
│       │   └── logback.xml
│       └── webapp
│           ├── WEB-INF
│           │   ├── views
│           │   │   └── hello.html
│           │   ├── appconfig-mvc.xml
│           │   ├── appconfig-root.xml
│           │   └── web.xml
│           └── resources
│               ├── css
│               │   └── main.css
│               └── js
│                   └── main.js
└── pom.xml

Project dependencies

pom.xml

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hellokoding.springmvc</groupId>
    <artifactId>springmvc-xml-thymeleaf</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <jdk.version>1.8</jdk.version>
        <spring.version>5.1.5.RELEASE</spring.version>
        <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
        <junit.version>4.12</junit.version>
        <logback.version>1.2.3</logback.version>
        <jetty-maven-plugin.version>9.4.15.v20190215</jetty-maven-plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>${thymeleaf.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
                <source>${jdk.version}</source>
                <target>${jdk.version}</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>${jetty-maven-plugin.version}</version>
            <configuration>
                <scanIntervalSeconds>10</scanIntervalSeconds>
                <webApp>
                    <contextPath>/</contextPath>
                </webApp>
            </configuration>
        </plugin>
        </plugins>
    </build>
</project>

Define Controller and View Template

Hello Controller

Controller maps HTTP Requests with View.

HelloController.java

package com.hellokoding.springmvc;

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

@Controller
public class HelloController {
    @GetMapping({"/", "/hello"})
    public String hello(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
        model.addAttribute("name", name);
        return "hello";
    }
}

@RequestMapping maps /hello request to hello() method.

name is a query string parameter of /hello request.

Model object passes value to hello view (hello.html).

Thymeleaf View Template

Thymeleaf performs server side rendering for the HTML content. It parses the hello.html template below and evaluate the Spring EL (Expression Language) to render the value of ${name} parameter that was set in the controller.

hello.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    <title th:text="'Hello ' + ${name} + '!'"></title>
    <link th:href="@{/resources/css/main.css}" rel="stylesheet"/>
</head>
<body>
    <h2 class="hello-title" th:text="'Hello ' + ${name} + '!'"></h2>
    <script th:src="@{/resources/js/main.js}"></script>
</body>
</html>

Static files

main.css

.hello-title{
    color: darkgreen;
}

main.js

(function(){
    console.log("Hello World!");
})();

Config and Run

XML Configurations

An application usually has several XML configuration files, but there should only one bootstrap file (appconfig-root.xml). This bootstrap file should use the <import resource="" /> to include other config files.

appconfig-root.xml

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

    <import resource="appconfig-mvc.xml"/>

    <context:component-scan base-package="com.hellokoding.*"/>

    <context:property-placeholder location="classpath:application.properties"/>

</beans>

appconfig-mvc.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <mvc:annotation-driven/>

    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <bean id="templateResolver"
          class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML5" />
    </bean>

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

    <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
    </bean>

</beans>

web.xml

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

    <display-name>Hello Spring MVC</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/appconfig-root.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

Run with Maven and Jetty

Type the below command at the project root directory and visit to localhost:8080

mvn clean jetty:run

Source code

https://github.com/hellokoding/hellokoding-courses/tree/master/spring-mvc-examples/springmvc-xml-thymeleaf

Follow HelloKoding