3.1 Spring Boot的第一个Web项目
打开IntelliJ IDEA,新建一个简单的项目,过程与第2章介绍的一致。
本人演示是用sts(Eclipse)开发工具
新建项目
生成项目如下图
3.1.1 加入Web依赖
创建项目后,在项目的pom文件中加入Web依赖,并且导入依赖文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aohai</groupId>
<artifactId>bootdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bootdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.1.2 创建Controller
新建一个HelloController,在类上加入注解@RestController,了解Spring MVC的都知道,这个注解是Spring 4.0版本之后的一个注解,功能相当于@Controller与@ResponseBody两个注解的功能之和。
在HelloController内创建方法hello(),在方法上加入注解@GetMapping("/hello"),这个注解是在Spring后期推出的一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写,将HTTP Get映射到方法上。让hello()返回一个字符串“你好吗?”。HelloController的完整内容如代码
package com.pbm.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "你好吗?";
}
}
3.1.3 测试运行
截至目前,其实简单的Web项目已经创建完成了,接下来启动项目。
首先运行项目,如图
其次观察一下控制台,我们似乎得到几个信息:项目的端口是8080、默认使用的Web容器是Tomcat、刚刚写的hello()在控制台有所映射。
在浏览器上访问http://localhost:8080/hello,可以看到浏览器打印了我们在方法内返回的内容。
到这里,一定会有人和笔者第一次接触的时候有同样的想法。Spring Boot项目太神奇了,完全颠覆了我们对传统Web项目的认识,它没有原有的web.xml文件,只需短短的几行代码,就完成了原有Spring MVC项目的烦琐配置,甚至连配置Tomcat都不需要,直接在内部提供了Tomcat。
3.2 WebFlux的使用(略)
3.3 使用热部署
热部署这个词汇大家听起来应该并不陌生,在Spring Boot框架中是否提供了相关的热部署呢?其实在第1章介绍Spring Boot框架的特点时已经指出了,只需要引入spring-boot-devtools依赖文件即可,十分简单。引入依赖后,重新编译修改的类文件或配置文件等,Spring Boot框架会自动替我们重启,spring-boot-devtools依赖如代码
在pom.xml增加依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
3.4 配置文件
3.4.1 配置文件类型
在src/main/java/resources目录下创建一个application.properties文件。
在这种情况下,我们使用配置的时候需要使用下面的格式(以端口号配置为例),如代码
server.port=8080
当然,我们也可以将配置文件application.properties后缀修改为.yml格式,即文件全名为application.yml。在这种格式下,端口配置如代码清单3-8所示。
3.4.2 自定义属性
前面介绍了两种配置文件的格式,这里以properties文件为例,在application.properties中自定义几个属性,如代码
book.theme=SpringBoot实战
book.author=pbm
在类中,如果需要读取配置文件的内容,那么只需要在属性上使用@Value("${属性名}"),新建一个TestController,在其中创建一个test1方法进行测试。TestController的完整内容如
package com.pbm.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Value("${book.theme}")
private String bookName;
@Value("${book.author}")
private String authorName;
@GetMapping("/test")
public String test() {
return "书名是"+bookName+"---"+"作者是"+authorName;
}
}
启动工程,在浏览器上访问http://localhost:8080/test,可以看到浏览器显示:“本书书名是:Spring Boot实战,作者是:pbm”。
注 意:
在application.properties中配置中文值,读取时会出现中文乱码问题。因为Java默认会使用ISO-8859-1的编码方式来读取*.properties配置文件,而SpringBoot应用则以UTF-8的编码方式来读取,就导致产生了乱码问题。
3.4.3 使用随机数
在配置文件中,还提供了随机数供我们使用,即在配置文件中使用${random}来生成不同类型的随机数,大致分为随机数、随机uuid、随机字符串等。在配置文件内添加几种利用随机数创建的属性,如代码
# 随机字符串
book.value=${random.value}
# 随机int值
book.intValue=${random.int}
# 随机long值
book.longValue=${random.long}
# 随机uuid
book.uuid=${random.uuid}
# 1000以内随机数
book.randomNumber=${random.int(1000)}
# 自定义属性间引用
book.title=${book.name}
在配置了这么多属性后,可以使用JavaBean模式来给属性赋值,创建一个BookConfigBean实体类。由于自定义属性的前缀都是由book开头的,因此我们可以在实体类上加入注解@ConfigurationProperties(prefix = “book”),同时需要在启动类上加入注解@EnableConfigurationProperties(BookConfigBean.class),表明启动这个配置类。实体类内容如代码清单3-12所示(这里省略了set、get方法)
到这里,配置就完成了。接下来在TestController中利用@Autowired注解注入BookConfigBean类,并且创建一个test2方法进行测试。test2方法及注入BookConfigBean类的内容如代码清单3-13所示。
在浏览器上访问http://localhost:8080/test2进行测试,显示结果如下:
3.4.4 多环境配置
在开发Spring Boot项目的时候,可能有这样的情况,一套程序需要在不同的环境中发布,数据库配置、端口配置或者其他配置各不相同,如果每次都需要修改为对应环境配置,不仅耗费人力,而且特别容易出现错误,造成不必要的麻烦。
通常情况下,我们可以配置多个配置文件,在不同的情况下进行替换。而在Spring Boot项目中,我们新建几个配置文件,文件名以application-{name}.properties的格式,其中的{name}对应环境标识,比如:
· application-dev.properties:开发环境。
· application-test.properties:测试环境。
· application-prod.properties:生产环境。
然后,可以在主配置文件(application.properties)中配置spring.profiles.active来设置当前要使用的配置文件。比如,在主配置文件中配置本次指定使用的配置文件后缀,配置内容如代码
spring.profiles.active=test
创建application-dev.properties配置文件,在文件中配置端口号为8081,配置文件内容如代码
# 配置端口号
server.port=8081
创建application-test.properties配置文件,在文件中配置端口号为8082,配置文件内容如代码。
# 配置端口号
server.port=8082
启动项目或者打成JAR包形式都会自动读取对应配置文件,可以在控制台看到启动端口号为8082。
3.4.5 自定义配置文件
前面介绍了多环境配置文件,我们也可以使用自定义配置文件,比如新建一个test.properties,配置文件内容如代码清单3-17所示。
代码清单3-17 test.properties配置文件
com.book.name=Spring Boot 2实战之旅
com.book.author=杨洋
与之前一样,新建一个javabean来读取配置文件。新建一个ConfigBean,在类上加上注解@PropertySource(value = “classpath:test.properties”),并且和之前一样需要加入@ConfigurationProperties(prefix = “com.book”),实体类代码如代码清单3-18所示(省略了set、get方法)。
同样,在TestController中注入bean并且创建测试方法,内容如代码清单3-19所示。
使用浏览器访问http://localhost:8080/test3,可以看到显示如下内容:
{"name":"Spring Boot 2实战之旅","author":"杨洋"}
3.5 使用页面模板
3.5.1 使用Thymeleaf
Thymeleaf是当今比较流行的模板框架,并且是Spring Boot官方推荐使用的模板框架。本小节介绍Spring Boot框架如何使用Thymeleaf,并且会对Thymeleaf框架的使用方法进行介绍。
首先创建项目,在项目中加入spring-boot-starter-thymeleaf依赖。这里需要提醒的是,由于Thymeleaf对HTML的校验特别严格,比如标签没有结束等可能会对不熟悉者造成未知的困惑,因此我们还需要加入nekohtml的依赖来避免这个“坑”。Thymeleaf依赖如代码清单
<!-- thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sourceforge.nekohtml/nekohtml -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
完成依赖的配置之后,我们需要在配置文件中对Thymeleaf进行配置,比如编码格式、缓存设置、文件前后缀等。配置文件内容如代码
## thymeleaf缓存是否开启,开发时建议关闭,否则更改页面后不会实时展示效果
spring.thymeleaf.cache=false
## thymeleaf编码格式
spring.thymeleaf.encoding=UTF-8
## thymeleaf对HTML的校验很严格,用这个去除thymeleaf严格校验
spring.thymeleaf.mode=LEGACYHTML5
## thymeleaf模板文件前缀
spring.thymeleaf.prefix=classpath:/templates/
## thymeleaf模板文件后缀
spring.thymeleaf.suffix=.html
到这里,准备工作已经完成。需要做的是创建一个Controller和HTML进行测试。新建一个IndexController,我们先写一个简单的路由跳转方法并且传一个字符串值进行测试。IndexController内容如代码
package com.pbm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/asd")
public String index(ModelMap modelMap) {
modelMap.addAttribute("msg", "hello,好久不见");
return "index";
}
}
然后,在src/mian/resources/templates下新建一个index.html(需要结合配置文件中spring.thymeleaf.prefix的配置信息存放HTML),使用th:text="${msg}"来接收后台传来的数据。index.html内容如代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 th:text="${msg}"></h1>
</body>
</html>
注意:
![在这里插入图片描述]()
启动项目,在浏览器上访问http://localhost:8081/asd,可以看到有如下显示:
到这里Spring Boot整合Thymeleaf已经完成,但是为了方便后面章节的使用,笔者在这里再介绍一下Thymeleaf模板的常用语法。
· th:text 设置当前元素的文本内容。
· th:value 设置当前元素的值。
· th:each 循环遍历元素,一般配合上面两者使用。
· th:attr 设置当前元素的属性。
· th:if th:switch th:case th:unless 用作条件判断。
· th:insert th:replace th:incloud 代码块引入,一般用作提取公共文件,或者引用公共静态文件等。
当然,Thymeleaf也提供了一些内置方法供我们使用,比如:
· #numbers 数字方法。
· #dates 日期方法。
· #calendars 日历方法。
· #strings 字符串方法。
· #lists 集合方法。
· #maps 对象方法。
关于Thymeleaf先了解到这里,后面的章节会对它有具体的实战使用,这里就不再赘述了。
Spring Boot整合Thymeleaf源码下载
百度网盘链接:https://pan.baidu.com/s/1E5n2lFTfhj2uHW9ivhEdmA
提取码:ifh8
3.5.2 使用FreeMarker
刚刚介绍了Thymeleaf模板,接下来我们学习FreeMarker模板,无论是语法还是配置等,两者都有很多相似的地方。接下来,我们学习Spring Boot项目整合FreeMarker模板。
新建项目,在项目中加入Freemarker依赖,如代码清单3-24所示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
接下来配置FreeMarker模板属性,与Thymeleaf模板配置类似,唯一需要注意的是模板文件后缀配置的是FTL文件。
配置文件如代码
## freemarker缓存是否开启
spring.freemarker.cache=false
## freemarker编码格式
spring.freemarker.charset=UTF-8
## freemarker模板文件前缀
spring.freemarker.template-loader-path=classpath:/templates/
## freemarker模板文件后缀,注意这里后缀名是.ftl
spring.freemarker.suffix=.ftl
接下来,创建一个TestController.java进行测试,内容如代码清单3-26所示。
package com.pbm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@RequestMapping("/test")
public String testFreemarker(ModelMap modelMap){
modelMap.addAttribute("msg", "你好, 这是freemarker");
return "freemarker";
}
}
在src/resources/templates下新建freemarker.ftl(注意文件后缀),使用${msg}接收后来传送的数据,文件内容如代码清单3-27所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>FreeMarker</title>
</head>
<body>
<h1>${msg}</h1>
</body>
</html>
到这里,项目配置完成。启动项目,在浏览器上访问http://localhost:8080,可以看到如下结果:
springboot整合FreeMarker源码
百度网盘链接:https://pan.baidu.com/s/1pSEorLkFl5N-nxsExKw9dw
提取码:pkty
复制这段内容后打开百度网盘手机App,操作更方便哦
接下来介绍FreeMarker的常用语法。
(1)通用赋值:${xxx}格式
· 比如后台返回键值aaa=string,可以使用${aaa?string},输出“Hi , Dalaoyang !”。
· 比如后台返回键值aaa=“2018-08-01 23:59”,可以使用${aaa?string(“EEE,MMM d,yy”)},输出:星期二,八月 14,18。
· 比如后台返回键值aaa=false,可以使用${aaa?string(“是”,“否”)},输出:否。
(2)数值赋值:#{xxx}或者#{xxx;format}格式
后者format可以是以下格式(其中X和Y为数字):
· mX 小数部分最小X位,比如后台返回值aaa=3.782131,可以使用#{x;m2},输出3.78。
· MX 小数部分最大X位,比如后台返回值aaa=3.782131,可以使用#{x;M3},输出3.782。
· mXMY 小数部分最小X位,最大Y位,比如后台返回值aaa=3.782131,可以使用#{x;m1M3},输出3.782。
(3)常用内建函数
· html 对字符串进行HTML编码。
· lower_case 字符串转小写。
· upper_case 字符串转大写。
· trim 去前后空格。
· size 获取集合元素数量。
· int 获取数字部分。
(4)常用指令
· if elseif else 分支控制语句。
· list 输出集合数据。
· import 导入变量。
· include 类似于包含指令。
3.6 使用WebJars
在开发的过程中,很多时候需要结合前端进行开发。本节将介绍Spring Boot框架整合WebJars进行前端静态JavaScript和CSS。
作为开发者,对Bootstrap和jQuery应该不会陌生。接下来我们将在Spring Boot项目中引入WebJars,对应二者的JAR进行使用,在pom文件中加入二者的依赖文件,如代码清单3-32所示。
其实到这里整合完毕了,但是为了证实我们是否可以成功引用,在src/main/recources/static文件夹下新建index.html,在HTML中引入刚刚加入依赖的文件。index.html页面代码如代码清单3-33所示
在HTML页面中,我们分别对Bootstrap和jQuery进行了引用,使用Bootstrap对a标签进行了样式的修饰,使用jQuery在打开页面时利用告警输出了a标签的href值。启动项目,让我们来证实一下,在浏览器上访问http://localhost:8080,如图3-5所示。如图3-5所示,可以看到之前的操作都实现了。其实WebJars还提供了很多其他的依赖,具体使用可以查看WebJars官网(官网地址:https://www.webjars.org/)。
3.7 国际化使用
本节使用的依赖文件与3.5节使用Thymeleaf所使用的依赖文件以及配置文件完全一致,这里不再展示。
Spring Boot在默认情况下是支持国际化使用的,首先需要在src/main/resources下新建国际化资源文件,这里为了举例说明,分别创建如下三个文件:
messages.properties(默认配置),内容如代码
message = 欢迎使用国际化(默认)
messages_en_US.properties(英文配置),内容如代码
message = Welcome to internationalization (English)
messages_zh_CN.properties(汉语配置)
然后就到了国际化的重头戏,需要进行i18n的配置,这里新建配置类i18nConfig,这个类需要继承WebMvcConfigurerAdapter类。其中,在localeResolver()方法中设置默认使用的语言类型,在localeChangeInterceptor()方法中设置识别语言类型的参数,并且从继承类中实现addInterceptors()方法,用于拦截localeChangeInterceptor()方法,进而实现国际化。i18nConfig类代码如代码清单3-37所示。
改造默认生成的启动类,在类上加入SpringMVC注解@Controller,注入MessageSource类获取国际化资源,并且创建方法返回资源文件对应的数据,返回到前台。新增代码如代码清单3-38所示。
启动项目,在浏览器上访问http://localhost:8081/,显示的内容如图3-6所示。
单击页面中的English(US)英文按钮,显示的内容如图3-7所示。
这时你可能会有一个疑问,为什么没有显示默认的配置文件?这是因为在发送HTTP请求的时候,浏览器会根据你的请求头判断区域而进行系统设定。那么问题来了,怎么才会使用到默认的配置文件呢?其实很简单,浏览器根据系统区域在你的程序中找不到语言时,就会使用默认配置,比如,删除项目中英文和中文的配置,只留下一个默认配置,重启项目,再次访问http://localhost:8081/,显示的内容如图3-8所示。
这时就可以看到默认配置,而且即使你单击上面的两个切换语言的按钮,也不会有所改变,因为应用内现在只有这一种配置。