RequestMapping的映射URL模板

本文介绍了Spring MVC中如何通过URL模板匹配请求,并利用占位符变量和矩阵变量来处理复杂的URL路径。包括正则表达式、Ant路径模式等高级特性。

映射的URL中有占位符变量,符合这个映射关系的请求都会被这个handler方法处理,下面就是一个模板例子。

/template/hello/jack和/template/hello/devin等等这样形式的请求都会被处理

@Controller
@RequestMapping(value = "/template")
public class URLTemplateController {

    @RequestMapping(value = "/hello/{name}")
    @ResponseBody
    public String hello(@PathVariable(value = "name") String name){
        return String.format("hello %s", name);
    }
}

@PathVariable

获取占位符变量的值,上面那个例子name值就是jack或devin。支持多个占位符,可以是Map获取占位符变量值。

@RequestMapping(value = "/customer/{name}/order/{id}")
    @ResponseBody
    public String multiPathVariable(@PathVariable Map<String, String> vars){
        return String.format("name %s, id %s", vars.get("name"), vars.get("id"));
    }

注意:多个占位符使用map获取值,记得在beans 添加<mvc:annotation-driven/>,否则会报错误:Could not find @PathVariable [vars] in @RequestMapping


正则表达式

语法:{变量名:正则表达式},例如:只匹配单词字符的name

@RequestMapping(value = "/regexp/{name:\\w}")
    @ResponseBody
    public String regexp(@PathVariable(value = "name") String name){
        return String.format("hello %s", name);
    }

Ant路径模式

在映射URL中可以包含通配符(*),例如:/ant/*SpringMVC自动执行 ".*" 的后缀匹配,匹配/ant/user时,也会匹配/ant/user.*


占位符和路径模式比较

当一个URL匹配多个模式时,会找一个更具体模式进行匹配
a、模式中的 URI 模版变量和通配符的数量相对较少。如:/hotels/{hotel}/* 相对 /hotels/{hotel}/** 更具体
   b、两个模式中的 URI 模版变量和通配符数量相同时,更详细的那一个会认为相对适合。如 /foo/bar* 比 /foo/* 更具体
   c、当两个模式中变量个数详细程度相同时,模板比通配符更具体,如/hotels/{hotel}比/hotels/*更具体
   d、任意模式都比默认全匹配 /** 模式更具体;任意不包含两个通配符的模式都比前缀模式(如 /public/**) 更加具体。/public/path3/{a}/{b}/{c} 比 /public/** 更具体

矩阵变量

语法:每个矩阵变量用分号隔开,例如:/cars;color=red;year=2012,矩阵变量有多个值时,用逗号隔开,例如:color=red,green,blue,也可以这样color=red;color=green;color=blue。包含矩阵变量的URL必须是一个URL模板,才能确保请求被正确匹配到。
支持矩阵变量还需要在beans文件中加上配置:
<mvc:annotation-driven enable-matrix-variables="true"/>
@RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)
    @ResponseBody
    public String findPet(
            @MatrixVariable Map<String, String> matrixVars,
            @MatrixVariable(pathVar="petId") Map<String, String> petMatrixVars) {
        //matrixVars {q=[11, 22], r=[12], s=[23]}
        //petMatrixVars {q=[22], s=[23]}
        return matrixVars.toString()+"  "+petMatrixVars.toString();
    }
pathVar是指占位符变量(模板变量),即获取模板变量后面的矩阵变量



<think> 我们已经在之前的讨论中详细解释了Spring MVC的路径匹配原理。现在,用户提出了一个新问题:“我想了解Spring MVC保存URL映射的方法”。 根据引用内容,我们可以总结Spring MVC保存URL映射的方法主要依赖于注解和配置,具体如下: 1. **注解方式**(现代Spring MVC最常用的方法): - 使用`@RequestMapping`及其变体(如`@GetMapping`, `@PostMapping`等)在控制器方法上声明URL映射规则[^1][^3]。 - 示例代码: ```java @RestController public class MyController { @GetMapping("/hello") public String hello() { return "Hello"; } } ``` 这段代码将URL路径`/hello`映射到`hello()`方法。 2. **URI模板变量风格映射**: - 在`@RequestMapping`的路径中使用`{变量名}`定义动态部分,如`@RequestMapping("/users/{userId}")`[^2][^4]。 - 结合`@PathVariable`注解获取URL中的变量值。 3. **正则表达式风格映射**(增强的URI模板): - 格式为`{变量名:正则表达式}`,可以约束变量的格式[^2][^4]。 - 示例:`@RequestMapping("/products/{categoryCode:\\d+}-{pageNumber:\\d+}")`,这里`\d+`确保两个变量都是数字。 4. **Ant风格通配符**: - 支持`?`, `*`, `**`等通配符[^5]。 - 示例: - `@RequestMapping("/users/**")`:匹配任意多级路径(如`/users/1/orders`) - `@RequestMapping("/product?")`:匹配单个字符(如`/product1`) 5. **配置方式**(传统方法,现在较少使用): - 在XML配置文件中使用`<bean>`定义处理器映射,如: ```xml <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/user">userController</prop> <prop key="/admin/**">adminController</prop> </props> </property> </bean> ``` 这里将URL模式直接映射到控制器bean。 6. **保存机制**: - **启动时注册**:在应用启动时,`RequestMappingHandlerMapping`(负责处理注解驱动的映射)会扫描所有Spring bean,检测带有`@Controller`或`@RequestMapping`的类和方法,提取URL模式并注册到内部映射表中[^1]。 - **数据结构**:通常使用高效的数据结构(如Trie树或哈希表)存储URL模式与处理方法的映射关系,以便快速匹配请求。 - **处理器适配**:每个映射条目关联一个`HandlerMethod`对象,包含目标方法、控制器bean等信息。 7. **冲突解决**: - 若多个方法映射同一URL,启动时会报`Ambiguous mapping`错误。 - 解决方法:确保URL唯一,或通过HTTP方法区分(如`@GetMapping`和`@PostMapping`)。 总结:Spring MVC主要通过注解(如`@RequestMapping`)定义URL映射,并在启动时由`RequestMappingHandlerMapping`统一收集和保存。支持丰富的映射规则,包括静态路径、URI模板、正则表达式和Ant风格通配符[^1][^2][^3][^4][^5]。 §§相关问题§§ 1. 如何在Spring MVC中处理URL映射冲突?(例如两个控制器方法映射到同一路径) 2. 如何自定义Spring MVC的URL映射注册逻辑? 3. Spring MVC的URL映射与RESTful API设计有何关联? </think> ### Spring MVC保存URL映射的方法详解 Spring MVC通过多种机制保存URL映射关系,核心是将URL模式与处理器(控制器方法)建立关联并存储在内存映射表中。具体实现方式如下: #### 1. **注解驱动映射(主流方式)** 通过注解在控制器方法上直接声明URL映射规则: ```java @RestController public class UserController { // 基本路径映射 @GetMapping("/users") // 等价于 @RequestMapping(method=GET) public List<User> listUsers() { ... } // 保存路径: GET /users [^1][^3] // 带URI模板变量映射 @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { ... } // 保存路径: GET /users/{id} [^2][^4] // 正则表达式约束的映射 @GetMapping("/products/{code:\\d+}-{page:\\d+}") public Product getProduct(@PathVariable String code, @PathVariable int page) { // 只匹配数字格式路径如 /products/123-1 [^2][^4] } // Ant风格通配符 @PostMapping("/orders/**") public void processOrder() { ... } // 匹配多级路径如 /orders/submit/123 [^5] } ``` **保存机制**:应用启动时,`RequestMappingHandlerMapping`扫描所有`@Controller`类,解析`@RequestMapping`及其衍生注解,将路径模式与`HandlerMethod`对象关联存储在内存映射表(如`Map<RequestMappingInfo, HandlerMethod>`)中。 #### 2. **XML配置映射(传统方式)** 通过XML文件显式配置URL与处理器的关系: ```xml <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- 静态路径映射 --> <prop key="/home">homeController</prop> <!-- Ant风格通配符 --> <prop key="/admin/**">adminController</prop> <!-- 混合风格 --> <prop key="/products/**/{id}">productController</prop> [^5] </props> </property> </bean> ``` **保存机制**:`SimpleUrlHandlerMapping`在初始化时将配置的路径模式与处理器Bean的引用存入`LinkedHashMap`,保持配置顺序[^5]。 --- ### 映射存储的核心原理 1. **数据结构** 使用有序映射(如`LinkedHashMap`)存储路径模式与处理器的对应关系,遵循**最长路径优先**原则: - 路径`/users/update`优先匹配`/users/update`而非`/users/*` - 路径`/products/123`优先匹配`/products/{id}`而非`/products/**` [^5] 2. **冲突解决** 启动时检测重复映射路径,抛出`IllegalStateException`。例如以下配置会导致冲突: ```java @GetMapping("/users/{id}") public void method1() { ... } @GetMapping("/users/{code}") public void method2() { ... } // 冲突!相同路径模板 ``` 3. **动态合并** 类级与方法级注解合并为完整路径: ```java @RequestMapping("/api") // 类级 public class ApiController { @GetMapping("/users") // 方法级 public void list() { ... } // 最终路径: /api/users [^1] } ``` --- ### 路径匹配优先级规则 当多个模式匹配同一URL时,按**特定性降序**选择处理器: 1. 静态路径(如`/users/list`) 2. URI模板路径(如`/users/{id}`) 3. 单层通配符(如`/users/*`) 4. 多层通配符(如`/users/**`)[^5] > **示例**:请求`/products/123-456`的匹配顺序: > 1. `/products/123-456`(完全匹配) > 2. `/products/{code}-{page}`(模板匹配) > 3. `/products/**`(通配符匹配) --- ### 性能优化策略 Spring MVC通过以下方式优化映射查询: 1. **路径模式预排序**:启动时按长度和特定性排序 2. **快速失败机制**:优先匹配最可能命中的模式 3. **缓存机制**:对高频路径缓存匹配结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值