1.3 编写Spring 应用程序
1.3 编写Spring 应用程序
因为才刚刚开始,所以我们将从对
- 一个处理主页请求的控制器类
- 一个视图模板,定义了主页的外观
因为测试很重要,所以还将编写一个简单的测试类来测试主页。但首先…我们来写这个控制器。
1.3.1 处理web 请求
你将在第/
package tacos;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
可以看到,这个类是用 @Controller
注释的。@Controller
本身并没有做多少事情。它的主要目的是将该类识别为组件扫描的组件。由于 HomeController
是用 @Controller
注释的,因此HomeController
实例作为
实际上,其他一些注释(包括 @Component
、@Service
和 @Repository
)的用途与 @Controller
类似。你可以用任何其他的注解来有效地注释 HomeController
,它仍然可以工作。但是,选择 @Controller
更能描述该组件在应用程序中的角色。
home()
方法与控制器方法一样简单。它使用 @GetMapping
进行注释,以指示如果接收到根路径 /
的home
的 String
值外,它什么也不做。
此值被解释为视图的逻辑名称。如何实现该视图取决于几个因素,但是因为
为什么是
你可能想知道为什么选择
简单地说,我必须选择一些东西,我喜欢
模板名称由逻辑视图名称派生而来,它的前缀是
1.3.2 定义视图
为了保持你的主页简洁,它应该做的只是欢迎用户访问网站。下一个清单显示了定义
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
</head>
<body>
<h1>Welcome to...</h1>
<img th:src="@{/images/TacoCloud.png}" />
</body>
</html>
关于这个模板没有太多要讨论的。唯一值得注意的代码行是显示<img>
标记。它使用一个th:src
属性和一个 @{…}
表达式引用具有上下文相对路径的图片。除去这些,它只是一个
但是让我们再多讨论一下这个图片。我将把它留给你来定义一个你喜欢的
该图片是通过上下文相对路径
现在已经有了处理主页请求的控制器和呈现主页的视图模板,几乎已经准备好启动应用程序并看到它的实际运行效果了。但首先,让我们看看如何针对控制器编写测试。
1.3.3 测试控制器
在对
就主页而言,你将编写一个与主页本身复杂度相当的测试。你的测试将对根路径 /
执行一个
package tacos;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@WebMvcTest(HomeController.class)
public class HomeControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testHomePage() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(view().name("home"))
.andExpect(content().string(containsString("Welcome to...")));
}
}
关于这个测试,你可能注意到的第一件事是,它与 TacoCloudApplicationTests
类在应用到它的注释方面略有不同。HomeControllerTest
使用 @WebMvcTest
注释,而不是 @SpringBootTest
标记。这是HomeController
在
@WebMvcTest
还为测试MockMvc
对象中,以此用来测试来驱动模型。
testHomePage()
方法定义了要对主页执行的测试。它从 MockMvc
对象开始,执行针对 /
(根路径)的
-
响应应该有一个
HTTP 200 (OK)状态。 -
视图应该有一个合理的主页名称。
-
呈现的视图应该包含 “Welcome to…”
如果在 MockMvc
对象执行请求之后,这些期望中的任何一个都没有满足,那么测试就会失败。但是控制器和视图模板是为了满足这些期望而编写的,所以测试应该能够通过,或者至少能够通过一些表示测试通过的绿色提示。
控制器写好了,视图模板创建好了,测试通过了。看来你已经成功地实现了主页。但是,即使测试通过了,在浏览器中查看结果也会稍微让人更满意一些。毕竟,
1.3.4 构建并运行应用程序
正如有多种方法可以初始化
因为选择使用
虽然图
图
当应用程序启动时,将在控制台中看到一些
等一下,
现在应用程序已经启动,将
图
它可能没什么好看的。但这并不是一本关于平面设计的书。主页的简陋外观现在已经足够了。它为你了解
到目前为止,忽略了
1.3.5 了解Spring Boot DevTools
顾名思义,
-
当代码更改时自动重启应用程序
-
当以浏览器为目标的资源(如模板、JavaScript、样式表等)发生变化时,浏览器会自动刷新
-
自动禁用模板缓存
-
如果
H2 数据库正在使用,则在H2 控制台中构建
理解
自动重启应用程序
使用
更准确地说,当
当检测到更改时,
这种策略的缺点是对依赖项的更改在自动重新启动时不可用。这是因为类装入器包含依赖项库 不是自动重新加载。这意味着,每当在构建规范中添加、更改或删除依赖项时,都需要重新启动应用程序才能使这些更改生效。
自动刷新浏览器和禁用模板缓存
默认情况下,模板选项(如
但是,缓存的模板在开发时不是很好。缓存的模板使它不可能在应用程序运行时更改模板,并在刷新浏览器后查看结果。即使做了更改,缓存的模板仍将继续使用,直到重新启动应用程序。
但如果像我一样,甚至不想被点击浏览器的刷新按钮所累,如果能够立即在浏览器中进行更改并查看结果,那就更好了。幸运的是,
当
在
虽然项目还没有使用数据库,但这将在第
至此,已经编写了一个完整但简单的
1.3.6 回顾
回想一下是如何走到这一步的。简而言之,以下是构建基于
- 使用
Spring Initializr 创建了一个初始项目结构。 - 写了一个控制器类来处理主页请求。
- 定义了一个视图模板来呈现主页。
- 写了一个简单的测试类来检验上诉工作。
看起来很简单,不是吗?除了启动项目的第一步之外,所采取的每一个行动都是为了实现创建主页的目标。
事实上,编写的几乎每一行代码都是针对这个目标的。不计算import
这是使用
这到底是怎么回事?
在
Spring MVC 框架- 嵌入式
Tomcat Thymeleaf 和Thymeleaf 布局方言
它还带来了
- 在
Spring 应用程序上下文中配置bean 以启用Spring MVC - 将嵌入式
Tomcat 服务器配置在Spring 应用程序上下文中 - 为使用
Thymeleaf 模板呈现Spring MV C 视图,配置了一个Thymeleaf 视图解析器
简而言之,自动配置完成了所有繁重的工作,让你专注于编写实现应用程序功能的代码。如果你问我这样好不好,我会说这是一个很好的安排!
你的