3.1 @Controller注解
org.springframework.stereotype.Controller注解用于指示Spring类的实例是一个控制器。
@Controller注解优点
使用@Controller注解的类不需要继承特定的父类或者实现特定的接口,相对之前的版本实现Controller接口变得更加简单。
而且**Controller接口的实现类只能处理一个单一请求动作,而@Controller注解的控制器可以支持同时处理多个请求动作,更加灵活**。
@Controller的作用
@Controller用于标记一个类,使用它标记的类就是一个Spring MVC Controller对象,即一个控制器类。
组件扫描
Spring使用扫描机制査找应用程序中所有基于注解的控制器类。**分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解**,而使用@RequestMapping注解的方法才是真正处理请求的处理器。
为了保证Spring能找到控制器,需要完成如下这两件事情:
- 在
Spring MVC的配置文件的头文件中引入spring-context
- 使用
<context:component-scan/>元素
- 该元素的功能为:启动包扫描功能,以便注册带有
@Controller、@Service、@Repository、@Component等注解的类成为Spring的Bean。
<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;
@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">
<context:component-scan base-package="org.fkit.controller" /> <mvc:annotation-driven /> <mvc:default-servlet-handler />
<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
| <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/>会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个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,它就像一个检查员,对进入DispatcherServlet的URL进行筛查:
- 如果发现是静态资源的请求,就将该请求转由
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章中讲解.