Spring Boot Hello World Example – Thymeleaf

A Spring Boot web application example, using embedded Tomcat + Thymeleaf template engine, and package as an executable JAR file.

Technologies used :

  1. Spring Boot 1.4.2.RELEASE
  2. Spring 4.3.4.RELEASE
  3. Thymeleaf 2.1.5.RELEASE
  4. Tomcat Embed 8.5.6
  5. Maven 3
  6. Java 8

1. Project Directory

Create the following folders manually :

spring-boot-thymeleaf-hello-world-example

2. Project Dependencies

Declares spring-boot-starter-thymeleaf, it will get anything you need to develop a Spring + Thymeleaf web application.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<artifactId>spring-boot-web-thymeleaf</artifactId>
	<packaging>jar</packaging>
	<name>Spring Boot Web Thymeleaf Example</name>
	<description>Spring Boot Web Thymeleaf Example</description>
	<url>https://www.mkyong.com</url>
	<version>1.0</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.2.RELEASE</version>
	</parent>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>

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

		<!-- hot swapping, disable cache for template, enable live reload -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>

		<!-- Optional, for bootstrap -->
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<version>3.3.7</version>
		</dependency>

	</dependencies>
	
	<build>
		<plugins>
			<!-- Package as an executable jar/war -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Display project dependencies :


$ mvn dependency:tree

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring Boot Web Thymeleaf Example 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ spring-boot-web-thymeleaf ---
[INFO] org.springframework.boot:spring-boot-web-thymeleaf:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:1.4.2.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.4.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.4.2.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.7:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.1.7:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.21:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.21:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.21:compile
[INFO] |  |  +- org.springframework:spring-core:jar:4.3.4.RELEASE:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.17:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-web:jar:1.4.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.4.2.RELEASE:compile
[INFO] |  |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.6:compile
[INFO] |  |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.6:compile
[INFO] |  |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.6:compile
[INFO] |  |  +- org.hibernate:hibernate-validator:jar:5.2.4.Final:compile
[INFO] |  |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  |  +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO] |  |  |  \- com.fasterxml:classmate:jar:1.3.3:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.4:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.4:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.8.4:compile
[INFO] |  |  +- org.springframework:spring-web:jar:4.3.4.RELEASE:compile
[INFO] |  |  |  +- org.springframework:spring-aop:jar:4.3.4.RELEASE:compile
[INFO] |  |  |  \- org.springframework:spring-beans:jar:4.3.4.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-webmvc:jar:4.3.4.RELEASE:compile
[INFO] |  |     \- org.springframework:spring-expression:jar:4.3.4.RELEASE:compile
[INFO] |  +- org.thymeleaf:thymeleaf-spring4:jar:2.1.5.RELEASE:compile
[INFO] |  |  +- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile
[INFO] |  |  |  +- ognl:ognl:jar:3.0.8:compile
[INFO] |  |  |  +- org.javassist:javassist:jar:3.20.0-GA:compile
[INFO] |  |  |  \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile
[INFO] |  |  \- org.slf4j:slf4j-api:jar:1.7.21:compile
[INFO] |  \- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:1.4.0:compile
[INFO] |     \- org.codehaus.groovy:groovy:jar:2.4.7:compile
[INFO] +- org.springframework.boot:spring-boot-devtools:jar:1.4.2.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:1.4.2.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-context:jar:4.3.4.RELEASE:compile
[INFO] |  \- org.springframework.boot:spring-boot-autoconfigure:jar:1.4.2.RELEASE:compile
[INFO] \- org.webjars:bootstrap:jar:3.3.7:compile
[INFO]    \- org.webjars:jquery:jar:1.11.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.429 s
[INFO] Finished at: 2016-12-03T13:25:06+08:00
[INFO] Final Memory: 20M/309M
[INFO] ------------------------------------------------------------------------
spring-boot-devtools

This spring-boot-devtools helps to disable the caches and enable hot swapping so that developers will always see the last changes. Good for development. Read this – Spring Boot – Developer tools.

Try to modify the Thymeleaf templates or properties files, refresh the browser to see the changes take effect immediately.

3. Spring Boot

3.1 Annotate with @SpringBootApplication, that’s all. Run this class to start the Spring Boot web application.

SpringBootWebApplication.java

package com.mkyong;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootWebApplication {

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

}

3.2 A simple Spring controller class.

WelcomeController.java

package com.mkyong;

import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WelcomeController {

	// inject via application.properties
	@Value("${welcome.message:test}")
	private String message = "Hello World";

	@RequestMapping("/")
	public String welcome(Map<String, Object> model) {
		model.put("message", this.message);
		return "welcome";
	}

}

4. Thymeleaf + Resources + Static files

4.1 For Thymeleaf template files, put in src/main/resources/templates/

src/main/resources/templates/welcome.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Thymeleaf Hello World Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<link rel="stylesheet" type="text/css"
	href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />

<link rel="stylesheet" th:href="@{/css/main.css}"
	href="../../css/main.css" />

</head>
<body>

	<nav class="navbar navbar-inverse">
		<div class="container">
			<div class="navbar-header">
				<a class="navbar-brand" href="#">Spring Boot</a>
			</div>
			<div id="navbar" class="collapse navbar-collapse">
				<ul class="nav navbar-nav">
					<li class="active"><a href="#">Home</a></li>
					<li><a href="#about">About</a></li>
				</ul>
			</div>
		</div>
	</nav>

	<div class="container">

		<div class="starter-template">
			<h1>Spring Boot Web Thymeleaf Example</h1>
			<h2>
				<span th:text="'Message: ' + ${message}"></span>
			</h2>
		</div>

	</div>
	<!-- /.container -->

	<script type="text/javascript"
		src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>

</body>
</html>

4.2 For static files like CSS or Javascript, put in /src/main/resources/static/

/src/main/resources/static/css/main.css

h1{
	color:#0000FF;
}

h2{
	color:#FF0000;
}

4.3 For properties files, put in /src/main/resources/

/src/main/resources/application.properties

welcome.message: Hello Mkyong
Note
Read this Spring Boot Serving static content to understand the resource mapping.

5. Demo

5.1 Start the Spring Boot web app.


project$ mvn spring-boot:run

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

2016-12-03 14:04:07.203  INFO 7180 --- [  restartedMain] com.mkyong.SpringBootWebApplication      : Starting SpringBootWebApplication on MKYONG-WIN10 with PID 7180 (C:\spring-boot\spring-boot-examples\spring-boot-web-thymeleaf\target\classes started by mkyong in C:\spring-boot\spring-boot-examples\spring-boot-web-thymeleaf)
2016-12-03 14:04:07.205  INFO 7180 --- [  restartedMain] com.mkyong.SpringBootWebApplication      : No active profile set, falling back to default profiles: default
2016-12-03 14:04:07.392  INFO 7180 --- [  restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67af925a: startup date [Sat Dec 03 14:04:07 SGT 2016]; root of context hierarchy
2016-12-03 14:04:08.739  INFO 7180 --- [  restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-12-03 14:04:08.754  INFO 7180 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-12-03 14:04:08.755  INFO 7180 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-12-03 14:04:08.827  INFO 7180 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-12-03 14:04:08.827  INFO 7180 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1439 ms
2016-12-03 14:04:08.969  INFO 7180 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-12-03 14:04:08.976  INFO 7180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-12-03 14:04:08.977  INFO 7180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-12-03 14:04:08.978  INFO 7180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-12-03 14:04:08.980  INFO 7180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-12-03 14:04:09.196  INFO 7180 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67af925a: startup date [Sat Dec 03 14:04:07 SGT 2016]; root of context hierarchy
2016-12-03 14:04:09.242  INFO 7180 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.mkyong.WelcomeController.welcome(java.util.Map<java.lang.String, java.lang.Object>)
2016-12-03 14:04:09.247  INFO 7180 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-12-03 14:04:09.247  INFO 7180 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-12-03 14:04:09.277  INFO 7180 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-03 14:04:09.277  INFO 7180 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-03 14:04:09.319  INFO 7180 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-03 14:04:09.687  INFO 7180 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2016-12-03 14:04:09.724  INFO 7180 --- [  restartedMain] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-12-03 14:04:09.781  INFO 7180 --- [  restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-12-03 14:04:09.787  INFO 7180 --- [  restartedMain] com.mkyong.SpringBootWebApplication      : Started SpringBootWebApplication in 2.943 seconds (JVM running for 3.325)

5.2 Access http://localhost:8080

spring-boot-thymeleaf-hello-world-example-output

6. Build an executable JAR

6.1 Package the project to create an executable JAR file.


project$ mvn clean package

...
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring Boot Web Thymeleaf Example 1.0
[INFO] ------------------------------------------------------------------------
...
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ spring-boot-web-thymeleaf ---
[INFO] Building jar: C:\spring-boot\spring-boot-examples\spring-boot-web-thymeleaf\target\spring-boot-web-thymeleaf-1.0.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.4.2.RELEASE:repackage (default) @ spring-boot-web-thymeleaf ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.797 s
[INFO] Finished at: 2016-12-03T14:06:45+08:00
[INFO] Final Memory: 21M/437M
[INFO] ------------------------------------------------------------------------

6.2 Run It, access http://localhost:8080 again.


project$ java -jar target/spring-boot-web-thymeleaf-1.0.jar

Download Source Code

Download it – spring-boot-web-thymeleaf.zip (9 KB)

References

  1. Thymeleaf official website
  2. Spring Boot – Static content
  3. Deploying Spring Boot Applications
  4. Spring MVC – Inlucde CSS file
  5. Spring Boot – Developer tools
  6. Serving Web Content with Spring MVC
  7. Spring Boot Hello World Example – JSP

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
David
Guest
David

Hi, what is the correct way to change the .html files path? I want them inside webapp/WEB-INF/templates. I’ve tried with the templateResolver setPrefix official thymeleaf doc, adding at my application.yml the spring:thymeleaf:prefix: classpath:WEB-INF/templates (without classpath…) with another @bean definitios in stackoverflow but not working in any way… Any idea or advice?

sipun
Guest
sipun

Why I am getting 404 error

imran khan
Guest
imran khan

only Return…. welcome message not welcome.html page….

Saulo Falcão
Guest
Saulo Falcão

” org.springframework.boot spring-boot-starter-web “

veeresh
Guest
veeresh

whats the use of thymeleaf in spring boot

Rohit Basu
Guest
Rohit Basu

I have an issue in deploying the war file deployed in tomcat 8.5. i log the issue in https://stackoverflow.com/questions/47294386/issues-in-spring-boot-war-file-deployment-in-tomcat-server
Let me know if you have any solution

yoga
Guest
yoga

please help me, i have error for build spring boot using maven for deploy to apache tomcat 7, my css file success to load like , but my javascript file and has error message Failed to load resource: the server responded with a status of 404 (Not Found). how to config maven or tomcat for show /cms for js file?

yoga
Guest
yoga

css href=”/cms/webjars/bootstrap/3.3.6/css/bootstrap.min.css” and js src=”/webjars/bootstrap/3.3.6/js/bootstrap.min.js”

Tugrul
Guest
Tugrul

css files couldn’t include. I did like your sample but I got this error “NetworkError: 404 Not Found – http://localhost:8080/static/css/main.css“. How can I solve this?

Danntu
Guest
Danntu

Brother, you can’t be looking directly, cause it’s Spring Boot. You @RequestMapping (“/”) it mean http://localhost:8080/

Loi Nguyen
Guest
Loi Nguyen

1. add

org.webjars
webjars-locator

2. remove /static/ , only href=/css/main.css

Saulo Falcão
Guest
Saulo Falcão

Hey, I got the error message: “Error resolving template “welcome”, template might not exist or might not be accessible by any of the configured Template Resolvers”.

Then I found this thread on StackOverflow ( https://stackoverflow.com/questions/44361064/error-resolving-template-welcome-template-might-not-exist-or-might-not-be-acc )

I just added the following dependency and it worked:
org.springframework.boot spring-boot-starter-web

Banti kumar
Guest
Banti kumar

Can you suggest me that how can I con configure jsp views in Spring Boot. I have also used thymeleaf worked perfectly but there is some issues in jsp. Please help me as soon as possible.

Thank you,
Banti kumar

dinesh
Guest
dinesh

I built my project exactly same as explained here. but I keep getting the whitelabel error page 404.