2.4 使用视图控制器

2.4 使用视图控制器

到目前为止,我们已经为Taco Cloud应用编写了3个控制器。尽管这3个控制器服务于应用程序的不同功能,但是它们基本上都遵循相同的编程模型:

  • 它们都使用了@Controller注解,表明它们是控制器类,并且应该被Spring的组件扫描功能自动发现并初始化为Spring应用上下文中的bean;
  • 除了HomeController之外,其他的控制器都在类级别使用了@RequestMapping注解,据此定义该控制器所处理的基本请求模式;
  • 它们都有一个或多个带@GetMapping或@PostMapping注解的方法,指明了该由哪个方法来处理某种类型的请求。

我们所编写的大部分控制器都将遵循这个模式。但是,如果一个控制器非常简单,不需要填充模型或处理输入(在我们的场景中,也就是HomeController),那么还有一种方式可以定义控制器。请参考下面的程序清单2.15来学习如何声明视图控制器:也就是只将请求转发到视图而不做其他事情的控制器。

程序清单2.15 声明视图控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
package tacos.web;
import org.springframework.context.annotation.Configuration;
import
org.springframework.web.servlet.config.annotation.ViewControllerRegistry
;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}

关于WebConfig,最需要注意的事情就是它实现了WebMvcConfigurer接口。WebMvcConfigurer定义了多个方法来配置Spring MVC。尽管只是一个接口,但是它提供了所有方法的默认实现,只需要覆盖所需的方法即可。在本例中,我们覆盖了addViewControllers方法。

addViewControllers()方法会接收一个ViewControllerRegistry对象,我们可以使用它注册一个或多个视图控制器。在这里,我们调用registry的addViewController()方法,将“/”传递了进去,视图控制器将会针对该路径执行GET请求。这个方法会返回ViewControllerRegistration对象,我们马上基于该对象调用了setViewName()方法,用它指明当请求“/”的时候要转发到“home”视图上。

如前文所示,我们用配置类中的几行代码就替换了HomeController类。现在,我们可以删除HomeController了,应用的功能应该和之前完全一样。唯一需要注意的是,我们要重新找到第1章中的HomeControllerTest类,从@WebMvcTest注解中移除对HomeController的引用,这样测试类的编译才不会报错。

在这里,我们创建了一个新的WebConfig配置类来存放视图控制器的声明。但是,所有的配置类都可以实现WebMvcConfigurer接口并覆盖addViewController方法。举例来说,我们可以将相同的视图控制器声明添加到TacoCloudApplication引导类中,如下所示:

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
public class TacoCloudApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(TacoCloudApplication.class, args);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}

采用扩展已有配置类的方式能够避免创建新的配置类,从而减少项目中制件的数量。但是,我倾向于为每种配置(Web、数据、安全等)创建新的配置类,这样能够保持应用的引导配置类尽可能地整洁和简单。

在视图控制器方面,或者更通俗地来讲,在控制器将请求所转发到的视图方面,到目前为止,我们都是使用Thymeleaf来实现所有视图的。我很喜欢Thymeleaf,但是你可能想要为你的应用选择不同的模板模型,下面让我们来看一下Spring所能支持的众多视图方案。