Пример SPRING BOOT приложения в связке с встроенным сервером приложений Tomcat и движком шаблонов Thymeleaf в качестве исполняемого JAR-файла.
Технологии:
- Spring Boot 1.5.9.RELEASE
- Spring 4.3.13.RELEASE
- Thymeleaf 2.1.6.RELEASE
- Tomcat Embed 8.5.6
- Maven 3
- Java 8
содержание
1. Структура каталогов
2. Зависимости
Объявляем spring-boot-starter-thymeleaf зависимость, этого будет достаточно для создания простого веб приложения. Остальные зависимости spring boot подгрузит самостоятельно.
Я генерировал проект с помощью Spring boot initializer встроенного в Intellij Idea после чего добавил зависимость webjars — bootstrap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<?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> <groupId>ru.leodev.examples.spring-boot</groupId> <artifactId>spring-boot-web-thymeleaf</artifactId> <version>0.0.1</version> <packaging>jar</packaging> <name>Spring Boot Web Thymeleaf Example</name> <description>Spring Boot Web Thymeleaf Example</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- горячая подмена, выключенный кеш для шаблонов, включенный live reload --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <!-- Опционально, что бы не грузить ручками bootstrap--> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
[stextbox id=’info’ caption=’Spring-boot-maven-plugin’]обеспечивает необходимые библиотеки, помогает вашему проекту работать напрямю без необходимости дополнительно применять сервера приложений. Реализует возможность создания исполняемых jar/war файлов (Executable)[/stextbox]
Следующий инструмент по моему мнению просто незаменим в разработке приложений
[stextbox id=’info’ caption=’spring-boot-devtools’]автоматически проверяет изменения в скомпилированном коде и шаблонах, очень быстро обновляет их в запущенном проекте (hot reload) причем только «боевую» часть приложения. Так же включает в себя интеграцию с Live Reload и после установки расширения в браузере, достаточно скомпилировать проект в IDEA, чтобы он автоматом обновился в браузере и отключает кеширование.[/stextbox]
3. Spring Boot
3.1 Для запуска spring boot проекта достаточно указать аннотацию @SpringBootApplication
1 2 3 4 5 6 7 8 9 10 11 12 |
package ru.leodev.examples.springboot.springbootwebthymeleaf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootWebThymeleafApplication { public static void main(String[] args) { SpringApplication.run(SpringBootWebThymeleafApplication.class, args); } } |
3.2 Пример простого контроллера на spring
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package ru.leodev.examples.springboot.springbootwebthymeleaf.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Map; @Controller public class ExampleController { // с помощью этой аннотации значение из application.properties будет подставлено в поле message @Value("${welcome.message:test}") private String message = "Hello World"; @RequestMapping("/") public String home(Map<String, Object> model) { model.put("message", this.message); return "home"; } } |
4. Thymeleaf + ресурсы и статические файлы
4.1 Что бы использовать файлы шаблонов Thymeleaf , мы положим их в src/main/resources/templates/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Spring Boot Thymeleaf Привет Мир Пример</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="#">Домой</a></li> <li><a href="#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 --> <!-- JS лучше импортировать в конце файлов что бы во время выполнения скриптов вся DOM структура уже была загружена --> <script type="text/javascript" src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script> </body> </html> |
4.2 Статические файлы, такие как стили CSS или Javascript кладем в /src/main/resources/static/
Чаще всего я создаю для каждого из них свой подкаталог и соответственно меняю его в пути html импорта
1 2 3 4 5 6 7 |
h1{ color: #000080; } h2{ color: #ff6048; } |
4.3 Все properties файлы хранятся в корне директории ресурсов: /src/main/resources/
в моем случае spring сгенерировал его при создании проекта, поэтому мы лишь прописываем параметр для Внедрения зависимости(DI)
1 |
welcome.message: Injected Message! |
[stextbox id=’black’]Прочтите эту статью о Spring Boot Serving static content для общего понимания работы с ресурсами в Spring[/stextbox]
5. Запуск приложения
5.1 Запускаем наше spring boot приложение
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Spring Boot Web Thymeleaf Example 0.0.1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> spring-boot-maven-plugin:1.5.9.RELEASE:run (default-cli) > test-compile @ spring-boot-web-thymeleaf >>> [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ spring-boot-web-thymeleaf --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 2 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ spring-boot-web-thymeleaf --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ spring-boot-web-thymeleaf --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ spring-boot-web-thymeleaf --- [INFO] No sources to compile [INFO] [INFO] <<< spring-boot-maven-plugin:1.5.9.RELEASE:run (default-cli) < test-compile @ spring-boot-web-thymeleaf <<< [INFO] [INFO] --- spring-boot-maven-plugin:1.5.9.RELEASE:run (default-cli) @ spring-boot-web-thymeleaf --- [INFO] Attaching agents: [] 02:29:44.859 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : [] 02:29:44.861 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter/target/classes/, /spring-boot-autoconfigure/target/classes/, /spring-boot-starter-[\w-]+/, /spring-boot/target/classes/ , /spring-boot-actuator/target/classes/, /spring-boot-devtools/target/classes/] 02:29:44.862 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/D:/workspace/JAVA/TESTAPPS/spring-boot-examples-ld/spring-boot-web-thymeleaf/target/classes/] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.9.RELEASE) 2018-01-18 02:29:45.106 INFO 13724 --- [ restartedMain] .e.s.s.SpringBootWebThymeleafApplication : Starting SpringBootWebThymeleafApplication on LEOGAME-PC with PID 13724 (D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\target\cla sses started by LEO in D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf) 2018-01-18 02:29:45.106 INFO 13724 --- [ restartedMain] .e.s.s.SpringBootWebThymeleafApplication : No active profile set, falling back to default profiles: default 2018-01-18 02:29:45.293 INFO 13724 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@d33dc6: startup date [Thu Jan 18 02:29:45 MSK 2018]; root of context hierarchy 2018-01-18 02:29:46.458 INFO 13724 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2018-01-18 02:29:46.467 INFO 13724 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2018-01-18 02:29:46.468 INFO 13724 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.23 2018-01-18 02:29:46.550 INFO 13724 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2018-01-18 02:29:46.550 INFO 13724 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1260 ms 2018-01-18 02:29:46.643 INFO 13724 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2018-01-18 02:29:46.645 INFO 13724 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2018-01-18 02:29:46.645 INFO 13724 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2018-01-18 02:29:46.645 INFO 13724 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2018-01-18 02:29:46.645 INFO 13724 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2018-01-18 02:29:46.844 INFO 13724 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@d33dc6: startup date [Thu Jan 18 02:29:45 MSK 2018]; root of context hierarchy 2018-01-18 02:29:46.895 INFO 13724 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String ru.leodev.examples.springboot.springbootwebthymeleaf.controller.ExampleController.home(java.util.Map<java.lang.Strin g, java.lang.Object>) 2018-01-18 02:29:46.897 INFO 13724 --- [ 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.autoconfigur e.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2018-01-18 02:29:46.898 INFO 13724 --- [ 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.BasicErrorControlle r.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2018-01-18 02:29:46.918 INFO 13724 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-01-18 02:29:46.919 INFO 13724 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-01-18 02:29:46.942 INFO 13724 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-01-18 02:29:47.233 INFO 13724 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2018-01-18 02:29:47.309 INFO 13724 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-01-18 02:29:47.352 INFO 13724 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2018-01-18 02:29:47.355 INFO 13724 --- [ restartedMain] .e.s.s.SpringBootWebThymeleafApplication : Started SpringBootWebThymeleafApplication in 2.484 seconds (JVM running for 2.773) |
5.2 Открываем http://localhost:8080
6. Создаем исполняемый JAR
6.1 Упаковываем проект для создания исполняемого JAR файла.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf>mvn clean package [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Spring Boot Web Thymeleaf Example 0.0.1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.6.1:clean (default-clean) @ spring-boot-web-thymeleaf --- [INFO] Deleting D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ spring-boot-web-thymeleaf --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 2 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ spring-boot-web-thymeleaf --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ spring-boot-web-thymeleaf --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ spring-boot-web-thymeleaf --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ spring-boot-web-thymeleaf --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ spring-boot-web-thymeleaf --- [INFO] Building jar: D:\workspace\JAVA\TESTAPPS\spring-boot-examples-ld\spring-boot-web-thymeleaf\target\spring-boot-web-thymeleaf-0.0.1.jar [INFO] [INFO] --- spring-boot-maven-plugin:1.5.9.RELEASE:repackage (default) @ spring-boot-web-thymeleaf --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.341 s [INFO] Finished at: 2018-01-18T02:36:49+03:00 [INFO] Final Memory: 20M/48M [INFO] ------------------------------------------------------------------------ |
6.2 Запускаем и проверяем результат еще раз http://localhost:8080
1 |
project$ java -jar target/spring-boot-web-thymeleaf-1.0.jar |
Исходники: spring-boot-web-thymeleaf