Spring实战(第6版)
上QQ阅读APP看书,第一时间看更新

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

它们都使用了@Controller注解,表明它们是控制器类,并且应该被Spring的组件扫描功能自动发现并初始化为Spring应用上下文中的bean;

除HomeController之外的控制器都在类级别使用了@RequestMapping注解,据此定义该控制器所处理的基本请求模式;

它们都有一个或多个带@GetMapping或@PostMapping注解的方法,这些注解指明了该由哪个方法来处理某种类型的请求。

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

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

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引导类中,如下所示:

@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所能支持的众多视图方案。