5.2 编写基本的控制器

在 Spring MVC 中,控制器只是方法上添加了 @RequestMapping 注解的类,这个注解声明了它们所要处理的请求。

开始的时候,我们尽可能简单,假设控制器类要处理对 / 的请求, 并渲染应用的首页。程序清单 5.3 所示的 HomeController 可能是最简单的 Spring MVC 控制器类了。

程序清单 5.3 HomeController:超级简单的控制器
package spittr.web;

import static org.springframework.web.bind.annotation.RequestMethod.*;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

  @RequestMapping(value="/", method = GET)
  public String home(Model model) {
    return "home";
  }

}

你可能注意到的第一件事情就是 HomeController 带有 @Controller 注解。很显然这个注解是用来声明控制器的,但实际上这个注解对 Spring MVC 本身的影响并不大。

HomeController 是一个构造型(stereotype)的注解,它基于 @Component 注解。在这里,它的目的就是辅助实现组件扫描。因为 HomeController 带有 @Controller 注解,因此组件扫描器会自动找到 HomeController,并将其声明为 Spring 应用上下文中的一个 bean。

其实,你也可以让 HomeController 带有 @Component 注解,它所实现的效果是一样的,但是在表意性上可能会差一些,无法确定 HomeController 是什么组件类型。

HomeController 唯一的一个方法,也就是 home() 方法,带有 @Request-Mapping 注解。它的 value 属性指定了这个方法所要处理的请求路径,method 属性细化了它所处理的 HTTP 方法。在本例中,当收到对 / 的 HTTP GET 请求时,就会调用 home() 方法。

你可以看到,home() 方法其实并没有做太多的事情:它返回了一个 String 类型的 home 。这个 String 将会被 Spring MVC 解读为要渲染的视图名称。DispatcherServlet 会要求视图解析器将这个逻辑名称解析为实际的视图。

鉴于我们配置 InternalResourceViewResolver 的方式,视图名 home 将会解析为 /WEB-INF/views/home.jsp 路径的 JSP。现在,我们会让 Spittr 应用的首页相当简单,如下所示。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
  <head>
    <title>Spitter</title>
    <link rel="stylesheet" 
          type="text/css" 
          href="<c:url value="/resources/style.css" />" >
  </head>
  <body>
    <h1>Welcome to Spitter</h1>

    <a href="<c:url value="/spittles" />">Spittles</a> | 
    <a href="<c:url value="/spitter/register" />">Register</a>
  </body>
</html>

这个 JSP 并没有太多需要注意的地方。它只是欢迎应用的用户,并提供了两个链接:一个是查看 Spittle 列表,另一个是在应用中进行注册。图 5.2 展现了此时的首页是什么样子的。

在本章完成之前,我们将会实现处理这些请求的控制器方法。但现在,让我们对这个控制器发起一些请求,看一下它是否能够正常工作。测试控制器最直接的办法可能就是构建并部署应用,然后通过浏览器对其进行访问,但是自动化测试可能会给你更快的反馈和更一致的独立结果。所以,让我们编写一个针对 HomeController 的测试。

Last updated