Spring MVC 地址请求映射

1. 前言

本节课将和大家一起讲解 Spring MVC 的地址请求映射方案。通过本节课程的学习,你将了解到:

  • 如何使用注解的方式进行映射;
  • 如何对请求的 URL 进行筛选、过滤。

本章节内容相对而言较易理解,请掌握本章节中所提及的注解的使用。

2. @RequestMapping

什么是地址请求映射?

Spring MVC WEB 项目中,每一次请求都会交给用户控制器响应。为了保证用户能请求到用户控制器,则需要 Spring MVC 向外提供用户控制器对外的请求接口。这就是请求地址映射。

图片描述

如何映射?

答案是:可以使用 @RequestMapping 注解。

@RequestMapping 注解的作用:把用户控制器以 URL 逻辑名的方式向外映射,用于由外向内的请求调用。

Tips: 向外提供映射是 @RequestMapping 注解的事情。解析请求包中的信息,查找是否存在相匹配的控制器,这个工作由映射器组件完成。

2.1 @RequestMapping 的位置

@RequestMapping 注解既可以放置在类前面也可以放在方法前面。

@Controller
//类名前面                         
@RequestMapping("/user") 
public class UserController {
	 @RequestMapping(value = "/register") 
	 public String register() {
	           return “user/register”; 
	 }
}

如上代码,请求控制器中的 register() 方法的 URL 应该是 http://localhost:8888/user/register 。 如果类前面没 @RequestMapping 则访问的 URL 应该是 http://localhost:8888/register

如此可知,通过类前面添加 @RequestMapping 注解可以归类控制器的主体功能,窄化请求范围。

Tips: 可以把类前面 @RequestMapping 中提供的名字看成命名空间。

2.2 使用表达式限定请求

@RequestMapping 注解的映射描述具有多样性:

  • 支持标准的 URL 格式;
  • 支持 Ant 风格。

什么是 Ant 风格?

所谓 Ant 风格指在 URL 中支持 通配符的语法结构描述。 Ant 的通配符主要是 3 种:

  • ?: 匹配任何单字符;
  • * : 匹配 0 个或者任意数量的字符;
  • ** : 匹配 0 个或者更多的目录。

如下面的地址请求映射:

  • /user/*/saveUser:可匹配类似于 /user/aaa/saveUser、/user/bbb/saveUser 等请求 URL;

  • /user/**/saveUser:可以匹配 /user/saveUser、/user/aaa/bbb/saveUser 等请求 URL;

Tips : ** 可以表示多个目录。

  • /user/saveUser??:匹配 /user/saveUseraa、/user/saveUserbb 等请求 URL;

Spring MVC 的地址请求映射除了支持通配符外,还支持带 {xxx} 占位符的 URL。

如下面的地址请求映射:

  • /user/{userId}:可以匹配 user/1、user/2、user/123 等请求 URL;
  • /user/**/{userId}:可以匹配 user/aa/bbb/1、user/aaa/45 等请求 URL;
  • company/{companyId}/user/{userId}/detail:可以匹配 company/1/user/2/detail 等请求 URL。

2.3 限定请求的方法

先看一看 @RequestMapping 注解中提供的相关方法:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {	
	String name() default "";
	@AliasFor("path")
	String[] value() default {};
	@AliasFor("value")
	String[] path() default {};
	RequestMethod[] method() default {};
	String[] params() default {};
	String[] consumes() default {};
	String[] produces() default {};
}

其中有 2 个很实用的方法:

  • method():可限定请求的方法;
  • params():可以限定请求的参数。

先了解一下如何限定请求方法。

所谓限定请求方法,指用户控制器中的某些方法只响应特定的请求方法。

HTTP 协议中请求方法有多种,常用的请求方法如下:

  • GET: 一般用于查询请求,具有幂等性,多次相同的请求会返回相同的结果,所以可以使用浏览器缓存。不会影响系统的整体性能;
  • POST: 一般用于数据保存请求。不具有幂等性,多次操作会产生新的资源;
  • DELETE: 一般用于删除资源请求,可以多次删除;
  • PUT: 一般用于更新数据请求,也具有幂等性,无论更新多次性,结果都一样。

如下面的实例,test() 方法只能响应以 POST 方式发出的请求:

@RequestMapping
@RequestMapping(value="/test",method=RequestMethod.POST) 
public String test(){
    return "user/test1";   
}

RequestMethod 是一个枚举类型:

public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

你可以根据自己的需要为控制器中的方法设定响应不同的请求方式。

2.4 限定请求参数

限定请求参数和限定请求方法同工异曲。所谓限定请求参数,Spring MVC 会检查请求包中是否包含符合要求的请求参数。通过 @RequestMapping 注解中的 params() 方法实现参数筛选。

如下面的实例:

@RequestMapping(value="/test", params="userId") 
public String test(){
    ...   
}

test()方法只会响应请求包中包含有 userId 参数的 URL。

params()方法支持条件运算符构建的表达式。

  • params=“userId”: 指挥响应请求包中包含有名为 userId 参数的请求;
  • params="!userId" : 如果请求包中有名为 userId 的请求参数,则不响应,否则响应;
  • params=“userId!=1”: 对响应的请求有更多的要求,除了请求包中必须包含 userId 参数外,其值必须是 1;
  • params={“userId=1”,“userName”}: 响应的条件是,请求包中必须包含名为 userId 和 userName 这两个参数,且 userId 参数的值必须为 1。

Tips : 方法、参数限制可同时使用。

@RequestMapping(value="/test",method = RequestMethod.POST,params = {"userId"})
public String test() {
	return null;
}

2.5 限定头信息

所谓限定头信息,指 Spring MVC 可以通过 HTTP 请求包中的消息头信息进行过滤。如下面的实例:

@RequestMapping(value="/test",headers="content-type=text/*")
public String test(){
     ...   
}

test() 方法只会响应请求包中的内容类型为 text/* 的请求。

无论是方法限定、还是参数限定或是头信息限定,其本质都是检查请求包是否符合条件要求。

3. 小结

本节课和大家一起讲解了 Spring MVC 的地址请求映射,认识了 @RequestMapping 注解。此注解最主要的功能就是使用一个逻辑名把内部控制器或控制器中的方法暴露给使用者。

@RequestMapping 提供了很灵活的映射方案,也提供了相应的内部方法对请求 URL 进一步过滤、筛选。

记住这个注解的使用,你便能变着花样把控制器映射出去。