3.1 Spring Boot的第一个Web项目

打开IntelliJ IDEA,新建一个简单的项目,过程与第2章介绍的一致。

本人演示是用sts(Eclipse)开发工具

新建项目

springboot 整合 wkhtmltopdf springboot整合web_html


springboot 整合 wkhtmltopdf springboot整合web_配置文件_02


springboot 整合 wkhtmltopdf springboot整合web_html_03


生成项目如下图

springboot 整合 wkhtmltopdf springboot整合web_spring_04

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项目已经创建完成了,接下来启动项目。

首先运行项目,如图

springboot 整合 wkhtmltopdf springboot整合web_spring_05

其次观察一下控制台,我们似乎得到几个信息:项目的端口是8080、默认使用的Web容器是Tomcat、刚刚写的hello()在控制台有所映射。

springboot 整合 wkhtmltopdf springboot整合web_spring_06


在浏览器上访问http://localhost:8080/hello,可以看到浏览器打印了我们在方法内返回的内容。

springboot 整合 wkhtmltopdf springboot整合web_spring_07

到这里,一定会有人和笔者第一次接触的时候有同样的想法。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 配置文件类型

springboot 整合 wkhtmltopdf springboot整合web_spring_08

在src/main/java/resources目录下创建一个application.properties文件。
在这种情况下,我们使用配置的时候需要使用下面的格式(以端口号配置为例),如代码

server.port=8080

springboot 整合 wkhtmltopdf springboot整合web_html_09


当然,我们也可以将配置文件application.properties后缀修改为.yml格式,即文件全名为application.yml。在这种格式下,端口配置如代码清单3-8所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_10

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”。

springboot 整合 wkhtmltopdf springboot整合web_配置文件_11


注 意:

在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方法)

springboot 整合 wkhtmltopdf springboot整合web_spring_12


到这里,配置就完成了。接下来在TestController中利用@Autowired注解注入BookConfigBean类,并且创建一个test2方法进行测试。test2方法及注入BookConfigBean类的内容如代码清单3-13所示。

springboot 整合 wkhtmltopdf springboot整合web_html_13


在浏览器上访问http://localhost:8080/test2进行测试,显示结果如下:

springboot 整合 wkhtmltopdf springboot整合web_spring_14

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所示。

springboot 整合 wkhtmltopdf springboot整合web_html_15

使用浏览器访问http://localhost:8080/test3,可以看到显示如下内容:

springboot 整合 wkhtmltopdf springboot整合web_html_16

{"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>

springboot 整合 wkhtmltopdf springboot整合web_配置文件_17

完成依赖的配置之后,我们需要在配置文件中对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,可以看到有如下显示:

springboot 整合 wkhtmltopdf springboot整合web_html_18

到这里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 整合 wkhtmltopdf springboot整合web_spring_19

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所示。

springboot 整合 wkhtmltopdf springboot整合web_配置文件_20


其实到这里整合完毕了,但是为了证实我们是否可以成功引用,在src/main/recources/static文件夹下新建index.html,在HTML中引入刚刚加入依赖的文件。index.html页面代码如代码清单3-33所示

springboot 整合 wkhtmltopdf springboot整合web_配置文件_21


在HTML页面中,我们分别对Bootstrap和jQuery进行了引用,使用Bootstrap对a标签进行了样式的修饰,使用jQuery在打开页面时利用告警输出了a标签的href值。启动项目,让我们来证实一下,在浏览器上访问http://localhost:8080,如图3-5所示。如图3-5所示,可以看到之前的操作都实现了。其实WebJars还提供了很多其他的依赖,具体使用可以查看WebJars官网(官网地址:https://www.webjars.org/)。

springboot 整合 wkhtmltopdf springboot整合web_spring_22

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(汉语配置)

springboot 整合 wkhtmltopdf springboot整合web_配置文件_23


然后就到了国际化的重头戏,需要进行i18n的配置,这里新建配置类i18nConfig,这个类需要继承WebMvcConfigurerAdapter类。其中,在localeResolver()方法中设置默认使用的语言类型,在localeChangeInterceptor()方法中设置识别语言类型的参数,并且从继承类中实现addInterceptors()方法,用于拦截localeChangeInterceptor()方法,进而实现国际化。i18nConfig类代码如代码清单3-37所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_24


改造默认生成的启动类,在类上加入SpringMVC注解@Controller,注入MessageSource类获取国际化资源,并且创建方法返回资源文件对应的数据,返回到前台。新增代码如代码清单3-38所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_25


启动项目,在浏览器上访问http://localhost:8081/,显示的内容如图3-6所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_26


单击页面中的English(US)英文按钮,显示的内容如图3-7所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_27


这时你可能会有一个疑问,为什么没有显示默认的配置文件?这是因为在发送HTTP请求的时候,浏览器会根据你的请求头判断区域而进行系统设定。那么问题来了,怎么才会使用到默认的配置文件呢?其实很简单,浏览器根据系统区域在你的程序中找不到语言时,就会使用默认配置,比如,删除项目中英文和中文的配置,只留下一个默认配置,重启项目,再次访问http://localhost:8081/,显示的内容如图3-8所示。

springboot 整合 wkhtmltopdf springboot整合web_spring_28


这时就可以看到默认配置,而且即使你单击上面的两个切换语言的按钮,也不会有所改变,因为应用内现在只有这一种配置。