程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Spring Boot

    • Spring Boot - 自动配置
    • Spring Boot - 自定义starter
    • Spring Boot - 配置文件
    • Spring Boot - 自定义SpringApplication
    • Spring Boot - 生命周期与事件
    • Spring Boot - 事件驱动
    • Spring Boot - Bean 加载方式
    • Spring Boot - 容器资源感知与获取
    • Spring Boot - 定时任务
    • Spring Boot - 异步任务
    • Spring Boot - 内置日志
    • Spring Boot - 函数式 Web
    • Spring Boot - 响应式远程调用
    • Spring Boot - 接口文档
    • Spring Boot - 单元测试
    • Spring Boot - 内容协商
    • Spring Boot - 参数校验
    • Spring Boot - HTTP客户端工具
    • Spring Boot - 控制器请求映射
      • 1. @RequestMapping 基础概念
      • 2. URL 映射配置方式
        • 2.1 映射单个URL
        • 2.2 映射多个URL
        • 2.3 路径斜杠说明
      • 3. 五种URL映射方式
        • 3.1 标准映射
        • 3.2 Ant风格映射
        • 3.3 占位符映射
        • 3.4 请求方法限制
        • 3.5 请求参数限制
      • 4. 处理多个URL映射到同一方法
      • 5. 处理请求内容类型与响应格式
      • 6. 处理HTTP请求头
      • 7. 处理请求参数的高级用法
      • 8. 处理动态URI与正则表达式匹配
      • 9. 默认请求处理方法
      • 10. 请求映射简化注解
      • 11. 请求参数接收
    • Spring Boot - 请求参数接收
    • Spring Boot - 通用响应类
    • Spring Boot - 全局异常处理
    • Spring Boot - 整合Druid
    • Spring Boot - 整合Thymeleaf
    • Spring Boot - 国际化实现
    • Spring Boot - 自定义注解
  • Spring高级
  • Spring Boot
scholar
2022-12-22
目录

Spring Boot - 控制器请求映射

# Spring Boot 控制器请求映射

笔记

因为需要多个 URL 能同时映射进入一个方法(一个 RequstMapping),所以学习了 Spring Boot 的 Controller 映射请求方式

# 1. @RequestMapping 基础概念

Spring 4.3 版本引入了一系列注解,包括 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping 等,用于简化HTTP请求方法的映射工作,并更好地表达被注解方法的语义。

这些注解根据命名约定可以看出,每个注解都负责处理特定的HTTP请求方法类型:

  • @GetMapping 专门处理GET请求
  • @PostMapping 专门处理POST请求
  • 等等

@RequestMapping 注解可以应用在两个层级:

  • 控制器类级别 - 定义共同的路径前缀
  • 方法级别 - 定义具体的请求路径
/**
 * 示例控制器
 * 类级别的@RequestMapping定义路径前缀为/home
 */
@RestController  
@RequestMapping("/home")  // 定义基础路径前缀
public class IndexController {  
    /**
     * 处理根路径请求
     * 完整请求路径: hostname:port/home/
     */
    @RequestMapping("/")  
    String get() {  
        return "Hello from get";  
    }  
    
    /**
     * 处理index路径请求
     * 完整请求路径: hostname:port/home/index/
     */
    @RequestMapping("/index")  
    String index() {  
        return "Hello from index";  
    }  
}
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

请求映射的执行流程:

  1. 首先匹配类级别的 @RequestMapping
  2. 然后进入类内部,匹配方法级别的 @RequestMapping
  3. 两级路径组合形成完整的请求路径

# 2. URL 映射配置方式

# 2.1 映射单个URL

// 以下两种方式效果相同
@RequestMapping("/users")
@RequestMapping(value = "/users")
1
2
3

# 2.2 映射多个URL

// 以下两种方式效果相同
@RequestMapping({"/users", "/members"})
@RequestMapping(value = {"/users", "/members"})
1
2
3

# 2.3 路径斜杠说明

路径开头是否添加斜杠("/")都可以,但建议统一添加以保持一致性。例如:

  • @RequestMapping("") 与 @RequestMapping("/") 效果相同,都表示根路径
  • 使用 / 开头可以使路径更加明确,避免混淆

# 3. 五种URL映射方式

@RequestMapping 提供了五种不同的映射方式,以满足各种需求:

# 3.1 标准映射

标准URL映射是最直接、最简单的映射方式。

/**
 * 标准映射示例
 * 映射到单个确定的URL
 */
@RequestMapping("/hello")

/**
 * 多个确定URL的标准映射
 * 同时处理两个不同的URL
 */
@RequestMapping({"/hello", "/world/test"})
1
2
3
4
5
6
7
8
9
10
11

# 3.2 Ant风格映射

Ant风格使用通配符来灵活匹配URL。三种通配符的含义:

  • ?: 匹配当前目录下的任何单个字符
  • *: 匹配当前目录下的任意数量字符(包括0个)
  • **: 匹配任意数量的目录(包括0个)

解释: 当前目录指的是由两个 / 分隔的部分,例如 /xx/ 中的 xx 是一个目录。

/**
 * 匹配 /a/hello/, /b/hello/, /c/hello/ 等
 * ? 只匹配单个字符
 */
@RequestMapping("/?/hello/")

/**
 * 匹配 /any/hello, /anything/hello 等
 * * 可匹配任意字符
 */
@RequestMapping("/*/hello")

/**
 * 匹配 /hello, /any/hello, /any/path/hello 等
 * ** 可匹配包括0个在内的任意级目录
 */
@RequestMapping("/**/hello")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.3 占位符映射

通过 {} 定义路径变量,实现动态URL的处理。

/**
 * 用户信息查询接口
 * {userId}是路径变量,将自动映射到方法参数中
 */
@RequestMapping("/user/{userId}/show")
public User show(@PathVariable("userId") Long userId) {
    // 根据userId查询用户
    User user = userService.getById(userId);
    return user;
}
1
2
3
4
5
6
7
8
9
10

特别说明:

  • 当URL中的占位符值为纯数字时,可以根据需要选择接收类型(Long、Integer、String等)
  • @PathVariable("参数名") 不能简写为 @PathVariable,必须指定参数名

# 3.4 请求方法限制

限制接口只能通过特定的HTTP方法访问。

/**
 * 只接受POST方法的请求
 */
@RequestMapping(value="/hello", method=RequestMethod.POST)

/**
 * 同时接受GET和POST方法的请求
 */
@RequestMapping(value="/hello", method={RequestMethod.GET, RequestMethod.POST})
1
2
3
4
5
6
7
8
9

# 3.5 请求参数限制

通过params属性限制请求参数。

/**
 * 以下示例要求请求必须包含userId参数
 */
@RequestMapping(value="/user", params="userId")

/**
 * 以下示例要求请求不能包含userId参数
 */
@RequestMapping(value="/user", params="!userId")

/**
 * 以下示例要求请求必须包含userId参数且值不能为1
 */
@RequestMapping(value="/user", params="userId!=1")

/**
 * 以下示例要求请求必须同时包含userId和userName两个参数
 */
@RequestMapping(value="/user", params={"userId", "userName"})

/**
 * 以下示例要求请求必须包含userId和userName参数,
 * 且userId值必须为1,userName值不能为2
 */
@RequestMapping(value="/user", params={"userId=1", "userName!=2"})
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

# 4. 处理多个URL映射到同一方法

可以将多个不同的请求路径映射到同一个处理方法,增强代码复用性。

/**
 * 多URL映射示例
 * 以下URL均会映射到该方法:
 * - localhost:8080/home
 * - localhost:8080/home/
 * - localhost:8080/home/page
 * - localhost:8080/home/pageabc  (通配符匹配)
 * - localhost:8080/home/view/    (目录通配符匹配)
 * - localhost:8080/home/view/view
 * - 任何以/msg结尾的路径,如/home/a/b/msg
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {  
    @RequestMapping(value = {"", "/page", "page*", "view/*", "**/msg"})  
    String indexMultipleMapping() {  
        return "Hello from index multiple mapping.";  
    }  
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

此示例中,各种URL模式说明:

  • "" - 匹配基础路径 /home
  • "/page" - 匹配 /home/page
  • "page*" - 匹配所有以page开头的路径,如 /home/pageabc
  • "view/*" - 匹配 view目录下的任何路径,如 /home/view/anything
  • "**/msg" - 匹配任何以msg结尾的路径,无论目录层级多深

# 5. 处理请求内容类型与响应格式

通过produces和consumes属性控制请求和响应的媒体类型。

/**
 * 媒体类型控制示例控制器
 */
@RestController  
@RequestMapping("/home")  
public class IndexController { 
    /**
     * 指定响应类型为JSON
     * 方法将只处理Accept头为application/JSON的请求
     */
    @RequestMapping(value = "/prod", produces = {"application/JSON"})  
    @ResponseBody  
    String getProduces() {  
        return "Produces attribute";  
    }  

    /**
     * 指定接收的请求体类型
     * 方法将只处理Content-Type为application/JSON或application/XML的请求
     */
    @RequestMapping(value = "/cons", consumes = {"application/JSON", "application/XML"})  
    String getConsumes() {  
        return "Consumes attribute";  
    }  
} 
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

说明:

  • produces - 指定响应的内容类型,对应HTTP响应的Content-Type
  • consumes - 指定接收的请求内容类型,对应HTTP请求的Content-Type
  • 这些属性可以限制请求的匹配范围,实现更精确的API控制

# 6. 处理HTTP请求头

利用headers属性根据请求头内容筛选请求。

/**
 * 请求头控制示例
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {  
    /**
     * 只处理Content-Type为text/plain的请求
     */
    @RequestMapping(value = "/head", headers = {"content-type=text/plain"})  
    String post() {  
        return "Mapping applied along with headers";  
    }  
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14

多请求头处理示例:

/**
 * 处理多种内容类型的请求头
 * 同时接受Content-Type为text/plain或text/html的请求
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {
    @RequestMapping(value = "/head", headers = {"content-type=text/plain", "content-type=text/html"})
    String post() {  
        return "Mapping applied along with headers";  
    }  
}
1
2
3
4
5
6
7
8
9
10
11
12

# 7. 处理请求参数的高级用法

使用params元素可以让同一个URL路径根据不同的请求参数匹配到不同的处理方法。

/**
 * 基于请求参数值的路由控制
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {
    /**
     * 处理personId=10的请求
     * 例如: /home/fetch?personId=10
     */
    @RequestMapping(value = "/fetch", params = {"personId=10"})  
    String getParams(@RequestParam("personId") String id) {  
        return "Fetched parameter using params attribute = " + id;  
    }  
    
    /**
     * 处理personId=20的请求
     * 例如: /home/fetch?personId=20
     */
    @RequestMapping(value = "/fetch", params = {"personId=20"})  
    String getParamsDifferent(@RequestParam("personId") String id) {  
        return "Fetched parameter using params attribute = " + id;  
    }  
}  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

实际应用说明:

  • 同一URL路径/home/fetch可以根据参数值不同映射到不同的处理方法
  • 当访问/home/fetch?personId=10时,会执行getParams()方法
  • 当访问/home/fetch?personId=20时,会执行getParamsDifferent()方法
  • 这种方式可以实现基于参数值的复杂路由逻辑

# 8. 处理动态URI与正则表达式匹配

结合@PathVariable注解处理动态URI,还可以使用正则表达式进行路径匹配。

/**
 * 动态URI与正则表达式匹配示例
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {  
    /**
     * 处理动态id路径参数
     * 例如: /home/fetch/123
     */
    @RequestMapping(value = "/fetch/{id}", method = RequestMethod.GET)  
    String getDynamicUriValue(@PathVariable String id) {  
        System.out.println("ID is " + id);  // 日志输出获取的ID值
        return "Dynamic URI parameter fetched";  
    }  
    
    /**
     * 使用正则表达式限制路径参数格式
     * id必须是小写字母,name可以是任意字符
     * 例如: /home/fetch/abc/shirt
     */
    @RequestMapping(value = "/fetch/{id:[a-z]+}/{name}", method = RequestMethod.GET)  
    String getDynamicUriValueRegex(@PathVariable("name") String name) {  
        System.out.println("Name is " + name);  // 日志输出获取的name值
        return "Dynamic URI parameter fetched using regex";  
    }  
}
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

重要区别说明:

  • @PathVariable 用于从URI路径中提取变量值
  • @RequestParam 用于从查询参数中提取值
  • 正则表达式{id:[a-z]+}限制了id参数只能包含小写字母
  • 当访问/home/fetch/10/shirt时会抛出异常,因为10不符合[a-z]+正则表达式

# 9. 默认请求处理方法

在控制器中可以定义一个默认处理方法,处理向基础URI发起的请求。

/**
 * 默认处理方法示例
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {  
    /**
     * 默认处理方法,没有指定具体路径
     * 处理对/home的请求
     */
    @RequestMapping()  
    String defaultMethod() {  // 方法名修正为有效的Java标识符
        return "This is a default method for the class";  
    }  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

说明:

  • 当@RequestMapping没有指定任何值时,它会处理控制器基础路径的请求
  • 上例中,向/home发起的请求将由defaultMethod()方法处理
  • 这种方式可以为API提供默认的行为或响应

# 10. 请求映射简化注解

Spring 4.3引入了一系列组合注解,简化了请求映射的配置。这些注解是@RequestMapping的特定变体:

  • @GetMapping - 等价于@RequestMapping(method = RequestMethod.GET)
  • @PostMapping - 等价于@RequestMapping(method = RequestMethod.POST)
  • @PutMapping - 等价于@RequestMapping(method = RequestMethod.PUT)
  • @DeleteMapping - 等价于@RequestMapping(method = RequestMethod.DELETE)
  • @PatchMapping - 等价于@RequestMapping(method = RequestMethod.PATCH)
/**
 * 组合注解实战示例
 */
@RestController  
@RequestMapping("/home")  
public class IndexController {  
    /**
     * GET请求处理 - 获取人员列表
     */
    @GetMapping("/person")  
    public @ResponseBody ResponseEntity<String> getPerson() {  
        return new ResponseEntity<String>("Response from GET", HttpStatus.OK);  
    }  
    
    /**
     * GET请求处理 - 获取特定ID的人员
     */
    @GetMapping("/person/{id}")  
    public @ResponseBody ResponseEntity<String> getPersonById(@PathVariable String id) {  
        return new ResponseEntity<String>("Response from GET with id " + id, HttpStatus.OK);  
    }  
    
    /**
     * POST请求处理 - 创建人员
     */
    @PostMapping("/person")  
    public @ResponseBody ResponseEntity<String> postPerson() {  
        return new ResponseEntity<String>("Response from POST method", HttpStatus.OK);  
    }  
    
    /**
     * PUT请求处理 - 更新人员
     */
    @PutMapping("/person")  
    public @ResponseBody ResponseEntity<String> putPerson() {  
        return new ResponseEntity<String>("Response from PUT method", HttpStatus.OK);  
    }  
    
    /**
     * DELETE请求处理 - 删除人员
     */
    @DeleteMapping("/person")  
    public @ResponseBody ResponseEntity<String> deletePerson() {  
        return new ResponseEntity<String>("Response from DELETE method", HttpStatus.OK);  
    }  
    
    /**
     * PATCH请求处理 - 部分更新人员
     */
    @PatchMapping("/person")  
    public @ResponseBody ResponseEntity<String> patchPerson() {  
        return new ResponseEntity<String>("Response from PATCH method", HttpStatus.OK);  
    }  
}
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

使用组合注解的优势:

  • 代码更简洁、更具可读性
  • 明确表达了处理方法的意图和HTTP方法语义
  • 减少了应用程序的配置元数据
  • 符合RESTful API设计规范和最佳实践

# 11. 请求参数接收

针对不同的请求方式如何接收参数,请参考 Spring Boot - 请求参数接收 专题文档。

编辑此页 (opens new window)
上次更新: 2025/04/05, 20:16:54
Spring Boot - HTTP客户端工具
Spring Boot - 请求参数接收

← Spring Boot - HTTP客户端工具 Spring Boot - 请求参数接收→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式