Весенний ботинок Hello World пример - усы
Пример веб-приложенияSpring Boot с использованиемembedded Tomcat + Mustache template engine
и пакет в виде исполняемого файлаJAR
.
Используемые технологии:
-
Spring Boot 1.5.2.RELEASE
-
Весна 4.3.7. РЕЛИЗ
-
jmustache 1.13
-
Тимелист 2.1.5. ВЫПУСК
-
Tomcat Embed 8.5.11
-
Maven 3
-
Java 8
1. Каталог проектов
2. Зависимости проекта
Объявляетspring-boot-starter-mustache
, он получит все, что вам нужно для разработки веб-приложенияSpring + Mustache
.
pom.xml
4.0.0 spring-boot-web-mustache jar Spring Boot Web Mustache Example Spring Boot Web Mustache Example https://www.example.com 1.0 org.springframework.boot spring-boot-starter-parent 1.5.2.RELEASE 1.8 org.springframework.boot spring-boot-starter-mustache org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools true org.webjars bootstrap 3.3.7 org.springframework.boot spring-boot-maven-plugin
Показать зависимости проекта:
$ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Spring Boot Web Mustache Example 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ spring-boot-web-mustache --- [INFO] org.springframework.boot:spring-boot-web-mustache:jar:1.0 [INFO] +- org.springframework.boot:spring-boot-starter-mustache:jar:1.5.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.5.2.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.2.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.11:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.11:compile [INFO] | | | +- org.slf4j:jcl-over-slf4j:jar:1.7.24:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.24:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.24:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-web:jar:1.5.2.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.5.2.RELEASE:compile [INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.11:compile [INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.11:compile [INFO] | | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.11:compile [INFO] | | +- org.hibernate:hibernate-validator:jar:5.3.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.7:compile [INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile [INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.7:compile [INFO] | | +- org.springframework:spring-web:jar:4.3.7.RELEASE:compile [INFO] | | | +- org.springframework:spring-aop:jar:4.3.7.RELEASE:compile [INFO] | | | \- org.springframework:spring-beans:jar:4.3.7.RELEASE:compile [INFO] | | \- org.springframework:spring-webmvc:jar:4.3.7.RELEASE:compile [INFO] | | \- org.springframework:spring-expression:jar:4.3.7.RELEASE:compile [INFO] | \- com.samskivert:jmustache:jar:1.13:compile [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:1.5.2.RELEASE:test [INFO] | +- org.springframework.boot:spring-boot-test:jar:1.5.2.RELEASE:test [INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.5.2.RELEASE:test [INFO] | +- com.jayway.jsonpath:json-path:jar:2.2.0:test [INFO] | | +- net.minidev:json-smart:jar:2.2.1:test [INFO] | | | \- net.minidev:accessors-smart:jar:1.1:test [INFO] | | | \- org.ow2.asm:asm:jar:5.0.3:test [INFO] | | \- org.slf4j:slf4j-api:jar:1.7.24:compile [INFO] | +- junit:junit:jar:4.12:test [INFO] | +- org.assertj:assertj-core:jar:2.6.0:test [INFO] | +- org.mockito:mockito-core:jar:1.10.19:test [INFO] | | \- org.objenesis:objenesis:jar:2.1:test [INFO] | +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] | +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] | +- org.skyscreamer:jsonassert:jar:1.4.0:test [INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test [INFO] | +- org.springframework:spring-core:jar:4.3.7.RELEASE:compile [INFO] | \- org.springframework:spring-test:jar:4.3.7.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-devtools:jar:1.5.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot:jar:1.5.2.RELEASE:compile [INFO] | | \- org.springframework:spring-context:jar:4.3.7.RELEASE:compile [INFO] | \- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.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.796 s [INFO] Finished at: 2017-04-19T11:46:09+08:00 [INFO] Final Memory: 22M/437M [INFO] ------------------------------------------------------------------------
3. Весенний ботинок
3.1 Create a @SpringBootApplication
class. Запустите этот класс, чтобы запустить веб-приложение Spring Boot.
SpringBootWebApplication.java
package com.example; 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 controller class.
WelcomeController.java
package com.example; 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("${app.welcome.message}") private String MESSAGE = ""; @Value("${app.welcome.title}") private String TITLE = ""; @RequestMapping("/") public String welcome(Mapmodel) { model.put("title", TITLE); model.put("message", MESSAGE); return "welcome"; } // test 5xx errors @RequestMapping("/5xx") public String ServiceUnavailable() { throw new RuntimeException("ABC"); } }
4. Усы + Ресурсы + Статические файлы
4.1 For Mustache template files, put in src/main/resources/templates/
src/main/resources/templates/layout/header.html
{{title}}
src/main/resources/templates/layout/footer.html
src/main/resources/templates/welcome.html
{{>layout/header}}{{>layout/footer}}Spring Boot Web Mustache Example
{{message}}
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 error templates.
Note
Прочтите этотSpring Boot – Error Handling, чтобы понять, как работает страница сопоставления ошибок по умолчанию.
src/main/resources/templates/error.html
Something went wrong: {{status}} {{error}}
src/main/resources/templates/error/5xx.html
I'm a 5xx
4.4 For properties files, put in /src/main/resources/
/src/main/resources/application.properties
app.welcome.message: Hello Mkyong app.welcome.title: Spring Boot Mustache Hello World Example
Note
Прочтите этотSpring Boot Serving static content, чтобы понять отображение ресурсов.
5. Модульный тест
5.1 Unit test example to test above Spring Boot web application.
MustacheApplicationTests
package com.example; import static org.assertj.core.api.Assertions.assertThat; import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @DirtiesContext public class MustacheApplicationTests { @Autowired private TestRestTemplate restTemplate; @Test public void testMainPage() throws Exception { ResponseEntityentity = this.restTemplate.getForEntity("/", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).contains("Hello Mkyong"); } @Test public void test404Page() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); HttpEntity requestEntity = new HttpEntity (headers); ResponseEntity responseEntity = this.restTemplate.exchange("/uri-not-exist", HttpMethod.GET, requestEntity, String.class); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); assertThat(responseEntity.getBody()).contains("Something went wrong: 404 Not Found"); } @Test public void test5xxPage() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); HttpEntity requestEntity = new HttpEntity (headers); ResponseEntity responseEntity = this.restTemplate.exchange("/5xx", HttpMethod.GET, requestEntity, String.class); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); assertThat(responseEntity.getBody()).contains("I'm a 5xx"); } }
6. Demo
Примечание
. В среде IDE запустите аннотированный класс@SpringBootApplication
, и будет запущено все приложение Spring Boot.
6.1 Start the Spring Boot web app.
Терминал
project$ mvn spring-boot:run //... . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.2.RELEASE) 2017-04-19 12:17:38.014 INFO 6232 --- [ restartedMain] com.example.SpringBootWebApplication : Starting SpringBootWebApplication on MKYONG-WIN10 with PID 6232 (C:\spring-boot\spring-boot-examples\spring-boot-web-mustache\target\classes started by example in C:\spring-boot\spring-boot-examples\spring-boot-web-mustache) 2017-04-19 12:17:38.015 INFO 6232 --- [ restartedMain] com.example.SpringBootWebApplication : No active profile set, falling back to default profiles: default 2017-04-19 12:17:38.074 INFO 6232 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@af1619: startup date [Wed Apr 19 12:17:38 SGT 2017]; root of context hierarchy 2017-04-19 12:17:39.352 INFO 6232 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2017-04-19 12:17:39.370 INFO 6232 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service Tomcat 2017-04-19 12:17:39.372 INFO 6232 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.11 2017-04-19 12:17:39.481 INFO 6232 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2017-04-19 12:17:39.481 INFO 6232 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1410 ms 2017-04-19 12:17:39.649 INFO 6232 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2017-04-19 12:17:39.658 INFO 6232 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2017-04-19 12:17:39.659 INFO 6232 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2017-04-19 12:17:39.659 INFO 6232 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2017-04-19 12:17:39.660 INFO 6232 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2017-04-19 12:17:39.938 INFO 6232 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@af1619: startup date [Wed Apr 19 12:17:38 SGT 2017]; root of context hierarchy 2017-04-19 12:17:39.997 INFO 6232 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.example.WelcomeController.welcome(java.util.Map) 2017-04-19 12:17:39.997 INFO 6232 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/5xx]}" onto public java.lang.String com.example.WelcomeController.ServiceUnavailable() 2017-04-19 12:17:40.006 INFO 6232 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity > org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2017-04-19 12:17:40.006 INFO 6232 --- [ 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) 2017-04-19 12:17:40.041 INFO 6232 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-04-19 12:17:40.041 INFO 6232 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-04-19 12:17:40.090 INFO 6232 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-04-19 12:17:40.332 INFO 6232 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2017-04-19 12:17:40.373 INFO 6232 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-04-19 12:17:40.427 INFO 6232 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2017-04-19 12:17:40.435 INFO 6232 --- [ restartedMain] com.example.SpringBootWebApplication : Started SpringBootWebApplication in 2.737 seconds (JVM running for 3.124)
6.2 Access http://localhost:8080
6.2 Access http://localhost:8080/uri-not-exist
6.2 Access http://localhost:8080/5xx
6. Создайте исполняемый JAR
6.1 Package the project to create an executable JAR
file.
project$ mvn clean package
6.2 Run It, access http://localhost:8080 again.
project$ java -jar target/spring-boot-web-mustache-1.0.jar
Скачать исходный код
Скачать -spring-boot-web-mustache.zip (11 КБ)