3.1 @Controller注解

3.1 @Controller注解

org.springframework.stereotype.Controller注解用于指示Spring类的实例是一个控制器。

@Controller注解优点

使用@Controller注解的类不需要继承特定的父类或者实现特定的接口,相对之前的版本实现Controller接口变得更加简单。
而且**Controller接口的实现类只能处理一个单一请求动作,而@Controller注解的控制器可以支持同时处理多个请求动作,更加灵活**。

@Controller的作用

@Controller用于标记一个类,使用它标记的类就是一个Spring MVC Controller对象,即一个控制器类。

组件扫描

Spring使用扫描机制査找应用程序中所有基于注解的控制器类。**分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解**,而使用@RequestMapping注解的方法才是真正处理请求的处理器
为了保证Spring能找到控制器,需要完成如下这两件事情:

  1. Spring MVC的配置文件的头文件中引入spring-context
  2. 使用<context:component-scan/>元素
    • 该元素的功能为:启动包扫描功能,以便注册带有@Controller@Service@Repository@Component等注解的类成为SpringBean
    • <context:component-scan/>元素的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
      配置文件中的示例如下所示:
      1
      <context:component-scan base-package="org.fkit.controller" />

应该将所有控制器类都放在基本包下,并且指定扫描该包,即org.fkit.controller,而不应该指定扫描org.fkit包,以免Spring MVC扫描了无关的包.

示例: @Controller注解的使用

项目结构

展开/折叠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
G:\Desktop\随书源码\Spring+Mybatis企业应用实战(第2版)\codes\03\ControllerTest
├─src\
│ └─org\
│ └─fkit\
│ └─controller\
│ └─HelloWorldController.java
└─WebContent\
├─META-INF\
│ └─MANIFEST.MF
└─WEB-INF\
├─content\
│ └─helloWorld.jsp
├─lib\
│ ├─commons-logging-1.2.jar
│ ├─spring-aop-5.0.1.RELEASE.jar
│ ├─spring-aspects-5.0.1.RELEASE.jar
│ ├─spring-beans-5.0.1.RELEASE.jar
│ ├─spring-context-5.0.1.RELEASE.jar
│ ├─spring-context-indexer-5.0.1.RELEASE.jar
│ ├─spring-context-support-5.0.1.RELEASE.jar
│ ├─spring-core-5.0.1.RELEASE.jar
│ ├─spring-expression-5.0.1.RELEASE.jar
│ ├─spring-instrument-5.0.1.RELEASE.jar
│ ├─spring-jcl-5.0.1.RELEASE.jar
│ ├─spring-jdbc-5.0.1.RELEASE.jar
│ ├─spring-jms-5.0.1.RELEASE.jar
│ ├─spring-messaging-5.0.1.RELEASE.jar
│ ├─spring-orm-5.0.1.RELEASE.jar
│ ├─spring-oxm-5.0.1.RELEASE.jar
│ ├─spring-test-5.0.1.RELEASE.jar
│ ├─spring-tx-5.0.1.RELEASE.jar
│ ├─spring-web-5.0.1.RELEASE.jar
│ ├─spring-webflux-5.0.1.RELEASE.jar
│ ├─spring-webmvc-5.0.1.RELEASE.jar
│ └─spring-websocket-5.0.1.RELEASE.jar
├─springmvc-config.xml
└─web.xml

新建一个项目ControllerTest,加入所需的jar文件,示例代码如下

HelloWorldController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.fkit.controller;

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

/**
* HelloWorldController是一个基于注解的控制器, 可以同时处理多个请求动作,并且无须实现任何接口。
* org.springframework.stereotype.Controller注解用于指示该类是一个控制器
*/
@Controller
public class HelloWorldController
{
@RequestMapping("/helloWorld")
public String helloWorld(Model model)
{
// 向模型之中添加一个属性
model.addAttribute("message", "Hello World!");
return "helloWorld";
}

}

HelloWorldController是一个基于@Controller注解的控制器,helloWorld方法上面的@RequestMapping注解用来映射一个请求,@RequestMapping注解的参数:"/helloWorld"表示/helloWorld这个请求由helloWorld方法进行处理。 helloWorld方法接收一个org.springframework.ui.Model类型的参数,本例在model中添加了一个名为message的字符串对象,该对象可以在返回的视图当中通过request对象获取。最后,方法返回一个字符串helloWorld作为视图名称.

springmvc-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件 -->
<!-- 如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean -->
<context:component-scan
base-package="org.fkit.controller" />
<!-- 默认装配方案 -->
<mvc:annotation-driven />
<!-- 静态资源处理 -->
<mvc:default-servlet-handler />

<!-- 视图解析器 p:prefix属性表示前缀 p:suffix 表示后缀 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/content/" p:suffix=".jsp" />

</beans>

springmvc-config.xml文件配置信息解释如下:

映射URL和控制器

  • 由于使用了@Controller注解,因此不需要再在配置文件中使用XML如下描述Bean
    1
    2
    <!-- 配置Handle,映射"/hello"请求 -->
    <bean name="/hello" class="org.fkit.controller.HelloController"/>
  • <context:component-scan base-package="org.fkit.controller" />指定需要Spring扫描org.fkit.controller包及其子包下面的所有java文件。

使用默认装配方案

  • <mvc: annotation-driven />是一种简写形式,可以让初学者快速应用默认配置方案<mvc:annotation-driven/>会自动注册RequestMappingHandlerMappingRequestMappingHandlerAdapter两个Bean,这是Spring MVC@Controllers分发请求所必需的,并且还提供了:
    • 数据绑定支持、
    • @NumberFormatAnnotation支持、
    • @DateTimeFormat支持、
    • @Valid支持、
    • 读写XML的支持(JAXB)
    • 和读写JSON的支持(默认为Jackson)等功能。本例处理Ajax请求时,就使用到了对JSON的支持功能。

静态资源处理器

<mvc: default-servlet-handler/>Spring MVC静态资源处理器,在web.xml中,如果将DispatcherServlet请求映射配置为"/",则Spring MVC将捕获Web容器所有的请求,包括静态资源的请求,而引入类似<script src="js/jquery-1.1.0.min.js"/>这种静态资源文件的时候,DispatcherServlet会将"/"看成请求路径,找不到它的时候会导致提示404错误。
当在springmvc-config.xml中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.webservlet.resource.DefaultServletHttpRequestHandler,它就像一个检查员,对进入DispatcherServletURL进行筛查:

  • 如果发现是静态资源的请求,就将该请求转由web应用服务器默认的Servlet处理;
  • 如果不是静态资源的请求,才由DispatcherServlet继续处理。

视图解析器

最后配置了视图解析器InternalResourceViewResolver来解析视图,将View呈现给用户。视图解析器中配置的prefix属性表示视图的前缀,suffix表示视图的后缀,
例如返回的视图字符串是"helloWorld",经过视图解析器解析之后,视图的完整路径为前缀helloWorld后缀,也就是:/WEB-INF/content/helloWorld.jsp

使用默认的处理器映射器和处理器适配器

需要注意的是,此处没有配置处理器映射器处理器适配器,当用户没有配置这两项时, Spring会使用默认的处理器映射器和处理器适配器处理请求

web.xml

此外,还需要在web.xml文件中配置Spring MVC的前端控制器DispatcherServlet,因为每次配置基本一致此处不再赘述,读者可自行配置。

测试

部署ControllerTest这个Web应用,在浏览器中输入如下URL来测试应用:

1
http://localhost:8080/ControllerTest/helloWorld

之后,会看到浏览器中显示HelloWorld!,这表示Spring MVC访问成功。

用于参数绑定的注解

Spring MVC用于参数绑定的注解有很多,都在org.springframework.web.bind.annotation包中,根据它们处理的request的不同内容部分可以分为六类。

处理 请求参数和内容 部分的注解

@RequestMapp@RequestParam@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping@Requestbody.、@ResponseBody@RequestPart@RestController

处理 请求URL 部分的注解

@PathVariable@MatrixVariable@CrossOrigin

处理 请求头 部分的注解

@RequestHeader, @CookieValue

处理 属性类型 的注解

RequestAttribute@SessionAttribute@SessionAttributes@ModelAttribute

处理 异常类型 的注解

ExceptionHandler@ControllerAdvice@RestControllerAdvice@ResponseStatus

绑定 表单数据 的注解

@InitBinder

接下来重点讲解常用的Spring MVC注解。@InitBinder注解用于解决类型转换问题,在第6章中讲解。@RequestPart注解用于绑定multipart/form-data"参数,常用于文件上传,在第7章中讲解.