Spring Boot Hello World – Thymeleaf
Dưới đây là ví dụ về ứng dụng web Spring Boot, sử dụng embedded Tomcat + Thymeleaf template engine, và package được build thành file JAR.
Công nghệ sử dụng :
-
Spring Boot 1.4.2.RELEASE
-
Spring 4.3.4.RELEASE
-
Thymeleaf 2.1.5.RELEASE
-
Tomcat Embed 8.5.6
-
Maven 3
-
Java 8
1. Cấu trúc thư mục
2. Cấu trúc file pom.xml
Khai báo spring-boot-starter-thymeleaf
, nó sẽ lấy mọi thứ cần thiết để bạn phát triển web bằng Spring + Thymeleaf.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-web-thymeleaf-hello-world</artifactId>
<packaging>jar</packaging>
<name>Spring Boot Web Thymeleaf Example</name>
<description>Spring Boot Web JSP Example</description>
<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>
3. Spring Boot
3.1 Cài đặt anotation @SpringBootApplication
, đây là class chính để chạy web bằng spring boot
package fixbugdao.spring_boot_web_thymeleaf_hello_world;
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 Một ví dụ về controller trong Spring.
package fixbugdao.spring_boot_web_thymeleaf_hello_world;
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 HelloWorldController {
// Lay tu file 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 File Thymeleaf được đặt trong thư mục src/main/resources/templates/
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Boot Thymeleaf Hello World</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 Các file CSS hoặc Javascript được đặt trong thư mục /src/main/resources/static/
h1{
color:#0000FF;
}
h2{
color:#FF0000;
}
4.3 File properties được đặt trong thư mục/src/main/resources/
welcome.message: Hello fixbugdao
5. Cách chạy project
5.1 Chuột phải vào file SpringBootWebApplication.java, chọn Run As -> Java Application. Sau khi project được chạy port mặc định là 8080. Tomcat server đã được nhúng trong project, không cần phải sử dụng tomcat bên ngoài.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.2.RELEASE)
2019-01-05 15:51:14.700 INFO 7592 --- [ restartedMain] f.s.SpringBootWebApplication : Starting SpringBootWebApplication on DESKTOP-DLGRKJK with PID 7592 (E:\Freelancer\Github\fixbugdao\spring-boot-web-thymeleaf-hello-world\target\classes started by AdMins in E:\Freelancer\Github\fixbugdao\spring-boot-web-thymeleaf-hello-world)
2019-01-05 15:51:14.701 INFO 7592 --- [ restartedMain] f.s.SpringBootWebApplication : No active profile set, falling back to default profiles: default
2019-01-05 15:51:14.702 INFO 7592 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@53032c15: startup date [Sat Jan 05 15:51:14 ICT 2019]; root of context hierarchy
2019-01-05 15:51:15.036 INFO 7592 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2019-01-05 15:51:15.037 INFO 7592 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service Tomcat
2019-01-05 15:51:15.037 INFO 7592 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2019-01-05 15:51:15.043 INFO 7592 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-01-05 15:51:15.044 INFO 7592 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 342 ms
2019-01-05 15:51:15.065 INFO 7592 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2019-01-05 15:51:15.066 INFO 7592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-01-05 15:51:15.066 INFO 7592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-01-05 15:51:15.066 INFO 7592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2019-01-05 15:51:15.066 INFO 7592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2019-01-05 15:51:15.105 INFO 7592 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@53032c15: startup date [Sat Jan 05 15:51:14 ICT 2019]; root of context hierarchy
2019-01-05 15:51:15.109 INFO 7592 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String fixbugdao.spring_boot_web_thymeleaf_hello_world.HelloWorldController.welcome(java.util.Map<java.lang.String, java.lang.Object>)
2019-01-05 15:51:15.110 INFO 7592 --- [ 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)
2019-01-05 15:51:15.110 INFO 7592 --- [ 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)
2019-01-05 15:51:15.115 INFO 7592 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-01-05 15:51:15.115 INFO 7592 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-01-05 15:51:15.121 INFO 7592 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-01-05 15:51:15.147 INFO 7592 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2019-01-05 15:51:15.172 INFO 7592 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2019-01-05 15:51:15.179 INFO 7592 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2019-01-05 15:51:15.180 INFO 7592 --- [ restartedMain] f.s.SpringBootWebApplication : Started SpringBootWebApplication in 0.507 seconds (JVM running for 29.088)
5.2 Truy cập vào đường dẫn sau https://localhost:8080