SSMSpringMVC中的@RequestMapping注解(含源码解析)

Posted 假正经的小柴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSMSpringMVC中的@RequestMapping注解(含源码解析)相关的知识,希望对你有一定的参考价值。

@RequestMapping注解

推荐文献

一文掌握@RequestMapping注解

SpringMVC请求参数和路径变量

SpringMVC官方文档

路径匹配工具(AntPathMatcher vs PathPattern

Request Mapping

下面是官方解释

You can use the annotation to map requests to controllers methods. It has various attributes to match by URL, HTTP method, request parameters, headers, and media types. You can use it at the class level to express shared mappings or at the method level to narrow down to a specific endpoint mapping.@RequestMapping

意思就是说:可以通过该 @RequestMapping 注解去映射控制器(指MVC中的Controller端)中的相关方法。它内部有很多属性可以用来匹配 URL、HTTP 方法、请求参数、表头…。这个注解可以使用在类上,也可以使用在方法上。

注意:这个的Controller端是指一个普通Bean,用@Controller注解标注了,如果使用其他申明Bean 的方式(@Component,@Service,@Repository)的话,组件扫描不正确会出错的。

下面是 @RequestMapping 注解的源代码
看 @Target 元注解可以得出请求映射注解只能用在类和方法上。
看其相关属性也可以猜测上面的官方解释的合理性。

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

针对特定的 HTTP 方法,@ReuqestMapping 有特定快捷式变体(子注解):

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

源码分析,探索这些子注解的作用

小编知道,SpringMVC 中的核心处理器为 DispatcherServlet ,而它的 UML 类图如下:

而通过小编一阵瞎找,发现 DispatcherServlet 的父类 FrameworkServlet 中重写了 HttpServlet 中重载的那个 service 方法。


不仅如此, FrameworkServlet 还重写了 HttpServlet 利用模板方法设计模式所构的方法,而且这些方法最终去向都是 processRequest 方法。而 processRequest 方法是 final 类型的,然后它内部又调了doService 方法,是抽象的,其实现该方法的类即是子类 DispatcherServlet实现的。

小编脑袋瓜子逐渐变的清晰,这些‘子注解’无非就是去映射到特定的HTTP方法上,无非就是去利用好 HttpServlet 中重载的那个 service 方法,多了个判断请求方式。而如果直接使用 @RequestMapping 注解的话,就没有这个请求方式的判断。

当然也可以通过设置 @RequestMapping 中的 method 属性去设置请求方式(下面可以看见其默认值是空的)。

而其他‘子注解’是对该 method 属性进行了设置的。比如下面的 @GetMapping 注解。

下面是简单的测试。

@Controller
public class DemoAction2 
    @GetMapping("/demo")
    public String demo2()
        System.out.println("SpringMVC 测试2....");
        return "xmq";
    

@RequestMapping(value = "/demo3", method = RequestMethod.GET)
    public String demo3()
        System.out.println("demo3 测试....");
        return "xmq";
    

@RequestMapping注解的位置

1)此注解可加在方法上,是为此方法注册一个可以访问的名称(路径)。

2)此注解可以加在类上,相当于包名(虚拟路径),区分不同类中形同的action的名称。

测试一波:

@Controller
@RequestMapping("/xc")
public class DemoAction2 
    @GetMapping("/demo")
    public String demo()
        System.out.println("demo 测试....");
        return "xmq";
    

    @GetMapping("/demo2")
    public String demo2()
        System.out.println("demo2 测试....");
        return "xmq";
    


点击课程2后看控制台输出:

Ant 风格的路径匹配

当我们使用 @RequestMapping 进行路径映射的时候,有时路径是不好确定的。SpringMVC支持ant风格的路径。映射时可以使用以下规则匹配的URL:

  • ? 匹配一个字符
  • *匹配零个或多个字符
  • **匹配路径中的零个或多个目录

注意:在Spring MVC 5.3之前,都是默认以 org.springframework.util.AntPathMatcher 进行模式匹配,而之后是以 org.springframework.web.util.pattern.PathPattern为默认的模式匹配。
其中后者仅用了web中,前者还可以用于非web的模式匹配,但后者匹配速度更快。还有就是后者用 ** 匹配时不能放在中间。

@RequestMapping("/a?a/test")

@RequestMapping("/a*a/test")

@RequestMapping("/**/test")

再详细一点的介绍可以看一篇:

Spring5的新宠

测试

@Controller
@RequestMapping("/t?")
public class DataSubmitAction 

    @GetMapping("/demo1")
    public String demo1(String name,int age)
        System.out.println("name = " + name + ", age = " + age);
        return "xmq";
    


以上是关于SSMSpringMVC中的@RequestMapping注解(含源码解析)的主要内容,如果未能解决你的问题,请参考以下文章

带有数据库迁移插件的 Grails 3:类 [com.mypackage.security.RequestMap] 上的方法在 Grails 应用程序之外使用

OGNL表达式

请求&注解

SSM

springboot常用的注解

springboot常用的注解