分享

SpringMVC框架基础知识(4)

 海拥 2021-11-30

1. 关于@RequestMapping注解

在控制器类中,在处理请求的方法之前使用@RequestMapping,可以绑定请求路径与处理请求的方法,以至于当客户端请求该路径时,对应的方法就会被调用!

其实,还可以在控制器类的声明之前也添加该注解!例如:

@Controller
@RequestMapping("user")
public class UserController {
}

则该控制器中所有请求路径的资源名(各处理请求的方法之前配置的值)左侧都需要添加类上配置的值!

假设在以上UserController中,没有为类配置@RequestMapping之前,存在以下请求路径:

http://localhost:8080/springmvc/reg.do
http://localhost:8080/springmvc/login.do

注:以上路径中的springmvc是Context Path值。

为类配置了@RequestMapping("user")之后,请求路径就需要改为:

http://localhost:8080/springmvc/user/reg.do
http://localhost:8080/springmvc/user/login.do

在实际开发项目时,推荐为每一个控制器类之前配置该注解

在控制器类之前也配置了@RequestMapping后,其配置值会与方法之前的@RequestMapping的配置值组合起来,形成完整的路径,无论是将@RequestMapping配置在哪个位置,在配置注解属性时,框架会自动添加必要的/,并且两端多余的/都是会忽略的!例如,以下各种配置方式是完全等效的:

在类之前的配置在方法之前的配置
userlogin.do
user/login.do
/userlogin.do
/user/login.do
user/login.do
user//login.do
/user/login.do
/user//login.do

所以,在实际应用时,一般推荐使用以上表格中的第1种做法,或第4种做法,也就是“要么在注解参数的左侧都不添加/符号,要么都添加/符号”。

关于@RequestMapping注解,其源代码中存在:

@AliasFor("path")
String[] value() default {};

基于value是注解中的默认属性,所以,一直以来,使用@RequestMapping注解时配置的值,其实都是这个value属性的值,也就是说,以下2种配置方式是完全等效的:

@RequestMapping("reg.do")
@RequestMapping(value = "reg.do")

由于在注解中声明的value的类型是String[]数组,所以,以上2种配置与以下2种配置都是完全等效的:

@RequestMapping({ "reg.do" })
@RequestMapping(value = { "reg.do" })

当注解参数的类型是某种数组类型,且需要配置的值只有1个值时,将该属性直接配置为数组元素的值,或配置为数组类型的值,都是允许的,且是等效的!

同时,基本该属性是数组类型的,所以,其实是可以配置多个路径的,例如:

@RequestMapping({ "reg.do", "register.do" })

如果注解参数中为value属性配置了2个值,就表示“通过这2个配置的请求路径中的任何一个都可以使得映射的方法被调用”!

在注解的源代码中,还可以看到,在value属性的声明之前还添加了@AliasFor("path")注解,即表示“配置value属性与配置path属性是完全等效的,且配置方式也完全相同”,所以,在源代码中,还有:

/**
 * The path mapping URIs (e.g. {@code "/profile"}).
 * <p>Ant-style path patterns are also supported (e.g. {@code "/profile/**"}).
 * At the method level, relative paths (e.g. {@code "edit"}) are supported
 * within the primary mapping expressed at the type level.
 * Path mapping URIs may contain placeholders (e.g. <code>"/${profile_path}"</code>).
 * <p><b>Supported at the type level as well as at the method level!</b>
 * When used at the type level, all method-level mappings inherit
 * this primary mapping, narrowing it for a specific handler method.
 * <p><strong>NOTE</strong>: A handler method that is not mapped to any path
 * explicitly is effectively mapped to an empty path.
 * @since 4.2
 */
@AliasFor("value")
String[] path() default {};

如果一定要说valuepath的区别,就是path更加明确的表现了“语义”,并且,path属性是SpringMVC框架从4.2版本开始加入的!

在源代码中,还有:

/**
 * The HTTP request methods to map to, narrowing the primary mapping:
 * GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
 * <p><b>Supported at the type level as well as at the method level!</b>
 * When used at the type level, all method-level mappings inherit
 * this HTTP method restriction (i.e. the type-level restriction
 * gets checked before the handler method is even resolved).
 */
RequestMethod[] method() default {};

以上代码表示“可以配置method属性,其值是RequestMethod数组的”。

该属性的作用是“限制请求方式”,如果没有配置该属性,则允许使用任何请求方式,一旦配置了该属性,只要被配置了的若干种请求方式是允许的,没有被配置的请求方式是不允许的!

例如,配置为:

@RequestMapping(path="handle_login.do", method=RequestMethod.POST)

如果尝试使用GET方式对以上路径提交请求,将会出现405错误,错误提示信息为:

HTTP Status 405 – Method Not Allowed

Message : Request method 'GET' not supported

在SpringMVC中,还提供了一些较为高级的注解,这些注解就具有基础注解的综合属性,例如,@PostMapping就等效于@RequestMapping(method = RequestMethod.POST)!类似的,还有@GetMapping@PutMapping@DeleteMapping@PatchMapping……都是类似的效果,即“限制为特定的某1种请求方式”!

总的来说,如果在类的声明之前添加注解,就应该使用@RequestMapping,在处理请求的方法之前,如果要将请求类型限制为特定的某1种,则应该优先使用@GetMapping@PostMapping等注解,如果不限制请求方式,或限制的类型不只1种,则使用@RequestMapping

2. SpringMVC阶段小结

  • 【理解】SpringMVC框架的作用:主要解决了如何接收请求、如何给予响应的问题;
  • 【理解】SpringMVC的核心执行流程(参考流程图);
  • 【掌握】创建SpringMVC项目:配置pom.xml使得没有web.xml也不会报错,且添加spring-webmvc依赖,勾选Tomcat,创建启动入口类并重写其中的3个抽象方法,创建SpringMVC的配置类;
  • 【掌握】使用控制器处理客户端提交的请求:控制器类必须放在组件扫描的包或其子孙包中,控制器类必须添加@Controller注解,处理请求的方法之前需要添加@RequestMapping或对应更高级的注解来配置请求路径,方法应该是public权限的,返回值暂时是String类型表示“视图名称”,方法名称可以自定义,方法的参数列表可以按需设计;
  • 【掌握】当结合使用Thymeleaf时,需要先添加thymeleafthymeleaf-spring4thymeleaf-spring5依赖,并在SpringMVC的配置中类配置Thymeleaf的视图解析器;
  • 【掌握】接收请求参数的方式:直接将请求参数声明为处理请求的方法的参数,或将若干个请求参数封装起来并使用封装的类型作为处理请求的方法的参数;
  • 【掌握】将控制器中的数据转发到视图组件;
  • 【理解】转发与重定向的区别,并掌握正常的选取;
  • 【掌握】使用Session;
  • 【掌握】开发并配置拦截器;
  • 【掌握】@RequestMapping及相关高级注解的使用。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多