Spring MVC高级知识点:自定义请求匹配路径

开发 前端
希望根据请求中header['x-token']的不同值调用不同的接口。接口请求地址相同,根据不同的header信息调用不同的执行方法。

[[417331]]

环境:springboot2.2.10.RELEASE

自定义请求匹配

希望根据请求中header['x-token']的不同值调用不同的接口。接口请求地址相同,根据不同的header信息调用不同的执行方法。

在SpringMVC中可以通过自定义

RequestMappingHandlerMapping#getCustomMethodCondition来实现此功能。

自定义请求匹配通过实现RequestCondition接口自定义规则

系统默认提供了以下RequestCondition实现

Spring MVC高级知识点自定义请求匹配路径

自定义匹配条件

  1. public class CustomRequestCondition implements RequestCondition<CustomRequestCondition> { 
  2.      
  3.     private static final String X_TOKEN_NAME = "x-token" ; 
  4.  
  5.     private Method method ; 
  6.      
  7.     public CustomRequestCondition(Method method) { 
  8.         this.method = method ; 
  9.     } 
  10.      
  11.     // 当接口上有多个匹配规则时,进行合并操作 
  12.     @Override 
  13.     public CustomRequestCondition combine(CustomRequestCondition other) { 
  14.         return new CustomRequestCondition(other.method) ; 
  15.     } 
  16.  
  17.     // 核心方法:根据匹配的条件进行判断是否匹配,如果匹配则返回当前的对象,不匹配则返回null 
  18.     @Override 
  19.     public CustomRequestCondition getMatchingCondition(HttpServletRequest request) { 
  20.         AKF akf = method.getAnnotation(AKF.class) ; 
  21.         return akf != null ? buildToken(request, akf) : null ; 
  22.     } 
  23.  
  24.     // 当有多个都满足条件的时候,进行比较具体使用哪个 
  25.     @Override 
  26.     public int compareTo(CustomRequestCondition other, HttpServletRequest request) { 
  27.         return 0 ; 
  28.     } 
  29.      
  30.     // 判断请求header中的信息与注解中配置的信息是否一致 
  31.     private CustomRequestCondition buildToken(HttpServletRequest request, AKF akf) { 
  32.         String xToken = request.getHeader(X_TOKEN_NAME) ; 
  33.         if (xToken == null || xToken.length() == 0) { 
  34.             return null ; 
  35.         } 
  36.         return xToken.equals(akf.value()) ? this : null ; 
  37.     } 
  38.  

自定义HandlerMapping

  1. public class CustomMethodConditionRequestHandlerMapping extends RequestMappingHandlerMapping { 
  2.     @Override 
  3.     protected RequestCondition<?> getCustomMethodCondition(Method method) { 
  4.         return new CustomRequestCondition(method) ; 
  5.     } 

配置自定义的HandlerMapping

  1. @Configuration 
  2. public class CustomEndpointConfig extends WebMvcConfigurationSupport { 
  3.      
  4.     @Override 
  5.     protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { 
  6.         return new CustomMethodConditionRequestHandlerMapping() ; 
  7.     } 
  8.      

注册HandlerMapping我们也可以通过@Bean的方式,但是这种方式会使得你在定义多个相同接口地址的时候容器启动就会报错

而且@Bean的方式是向容器中注册一个HandlerMapping对象;而通过上面的方式就是替换系统默认的

RequestMappingHandlerMapping对象。两种方式是不一样的,一个是增加一个HandlerMapping,一个是替换系统默认的。

测试接口

  1. @RestController 
  2. @RequestMapping("/conditions"
  3. public class CustomMethodConditionController { 
  4.      
  5.     @GetMapping("/index"
  6.     public Object index() { 
  7.         return "custom method condition success" ; 
  8.     } 
  9.      
  10.     @GetMapping("/index"
  11.     @AKF 
  12.     public Object x() { 
  13.         return "x method invoke" ; 
  14.     } 
  15.      
  16.     @GetMapping("/index"
  17.     @AKF("x1"
  18.     public Object x1() { 
  19.         return "x1 method invoke" ; 
  20.     } 
  21.      
  22.     @GetMapping("/index"
  23.     @AKF("x2"
  24.     public Object x2() { 
  25.         return "x2 method invoke" ; 
  26.     } 
  27.      

上面的接口地址完全相关,只是有些有@AKF注解,有些没有。

如果通过@Bean注册一个HandlerMapping后,多个请求路径相同会报如下错误:

  1. Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'customMethodConditionController' method  
  2. com.pack.controller.CustomMethodConditionController#x() 
  3. to {GET /conditions/index}: There is already 'customMethodConditionController' bean method 
  4. com.pack.controller.CustomMethodConditionController#index() mapped. 
  5.     at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.validateMethodMapping(AbstractHandlerMethodMapping.java:636) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 
  6.     at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:603) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE] 

在以上的请求中如果请求中没有携带x-token信息或者是value值不被匹配那么请求会是404。

 

责任编辑:姜华 来源: 今日头条
相关推荐

2023-12-04 07:27:54

SpringMVC方法

2023-03-02 11:52:00

自定义自动配置

2016-05-30 17:31:34

Spring框架

2022-11-10 07:53:54

Spring参数校验

2024-01-24 11:59:44

Django自定义字段Python

2016-08-23 13:21:15

MVC路由视图

2009-11-24 15:11:21

ASP.NET MVC

2021-04-13 08:25:12

测试开发Java注解Spring

2010-08-17 14:56:00

HCNE认证

2011-04-15 12:25:21

BGP路由

2015-02-12 15:33:43

微信SDK

2009-07-22 15:27:39

ASP.NET MVC自定义路由

2011-03-17 09:45:01

Spring

2010-04-30 09:32:49

ASP.NET MVC

2015-02-12 15:38:26

微信SDK

2011-05-23 14:47:12

WordPress

2017-08-03 17:00:54

Springmvc任务执行器

2022-06-20 08:26:39

Spring容器类型转换

2023-12-22 15:32:20

2010-08-17 23:32:11

点赞
收藏

51CTO技术栈公众号