【SpringMVC】:请求映射

这篇博客主要了解 SpringMVC 中 Controller 类的编写,主要了解的是请求地址与 Controller 类中方法的映射。

文章目录

    • 1、SpringMVC的工作流程
    • 2、DispathcerServlet
    • 3、Controller
    • 4、请求映射
      • 4.1、注解的位置
      • 4.2、注解的属性
    • 5、处理 PUT 和 DELETE 请求方式

1、SpringMVC的工作流程

具体的工作流程图:

【SpringMVC】:请求映射_第1张图片

这张流程图有点复杂,我们一点点进行解读:

  1. 客户端用户发送请求至DispatcherServlet(前端控制器)。该控制器会过滤出哪些请求可以访问Servlet、哪些不能访问,并且会加载 XML 配置文件。
  2. DispatcherServlet(前端控制器)根据请求地址寻找对应的处理器映射。如果不存在映射,则判断是否有对应的资源,如果没有则返回404错误代码页面,如果有则返回对应的资源。如果存在映射,则通过HandlerMapping(处理器映射器)生成Handler(处理器)(处理器拦截器)(拦截器如果有则生成),然后返回给 DispatcherServlet(前端控制器)
  3. DispatcherServlet(前端控制器)拿到Handler(处理器)后,找到HandlerAdapter(处理器适配器),经过适配调用具体的Handler(处理器)(Controller,也叫后端控制器)。
  4. Handler(处理器controller)执行
  5. HandlerAdapter(处理器适配器)Handler(处理器controller) 执行后的结果 ModelAndView 对象返回给DispatcherServlet(前端控制器)
  6. DispatcherServlet(前端控制器)前端控制器将 ModelAndView 对象传给ViewReslover视图解析器
  7. ViewReslover视图解析器解析后返回具体 View。
  8. DispatcherServlet(前端控制器)根据 View 进行渲染视图(即将模型数据填充至视图中),并返回给客户端用户。

在上述几个流程中,提到几个组件,它们的具体作用:

  1. 前端控制器 DispatcherServlet:由框架提供,作用是接收请求,响应结果,相当于转发器,中央处理器。用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。

  2. 处理器映射器HandlerMapping:由框架提供,作用是负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
    等。

  3. 处理器适配器HandlerAdapter:作用是按照特定规则去执行Handler。通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

  4. 处理器Handler:需要自己开发,在编写Handler时按照 HandlerAdapter 的要求去做,这样适配器才可以去正确执行Handler。Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下 Handler 对具体的用户请求进行处理。

  5. 视图解析器View resolver:由框架提供,作用是将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等

  6. 视图View:View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

2、DispathcerServlet

从工作流程中可以看出,SpringMVC 中有两个核心,其中一个就是DispathcerServlet——前端控制器,还有一个是Controller——后端控制器。

前端控制器不需要我们去编写,这个由 SpringMVC 提供,但是需要进行一定的配置,具体的配置在之前已经讲解过了。

3、Controller

Controller是后端控制器,也是具体的需要编写代码的地方。它主要是获取 DispathcerServlet 传递的请求参数,调用具体的业务,然后进行相应的数据响应。如下就是一个简单的 Controller类

//创建一个简单的Controller类
@Controller
public class UserController {

    @RequestMapping("/user")
    public String user(){
        //具体操作
        return  "/user.html";
    }
}

4、请求映射

DispathcerServlet获取到请求信息之后,调用 HandlerMapping 处理器映射器,其目的是通过根据请求地址找到对应的 Controller 类和 Controller 中具体的方法。

@RequestMapping注解的作用就是请求和处理请求的控制器方法关联起来,建立映射关系。@RequestMapping注解有多种属性可以通过请求地址、请求方式、请求参数、标头进行映射,既通过属性设置来完成具体的请求映射:

4.1、注解的位置

@RequestMapping 标识一个类时,表示设置映射请求的请求路径的初始信息;当 @RequestMapping 标识一个方法时,表示设置映射请求的请求路径的具体信息。

当注解设置在整个类,请求URL 的第一级访问目录。当注解设置方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径。

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

   //请求地址必须是localhost://user/user_name
   @RequestMapping("/user_name")
   public String user_name(){
    //....
   }
} 

4.2、注解的属性

注解在使用过程中,可以设置一些属性完成具体的映射。

  • value属性用于映射请求地址,是一个字符串数组,可以同时映射多个请求地址:

    @RequestMapping (value = {"/user_name","/user_names"})
    public void user_name() {
          // ...
    }
    

    在匹配请求路径时,除了可以直接设置请求地址,还可以使用ant风格的路径

    • ?:表示任意的单个字符
    • *:表示任意的0个或多个字符
    • **:表示任意的一层或多层目录
    @RequestMapping (value = {"/user_?ame","/user_names/*","/user_names/**"})
    public void user_name() {
          // ...
    }
    

    在匹配请求路径是,还可以使用占位符,然后通过@PathVariable注解将占位符表示的数据赋值给控制方法的形参。

    //@PathVariable("userId") 中的 userId 表示将占位符中的userId赋值形参,如果形参的参数和占位符中的相同可以省略("userId")
    @RequestMapping ("/user/{userId}/photos/{photoId}")
    public void findPet(@PathVariable("userId") Long userId, @PathVariable("photoId") Long photoId) {
          // ...
    }
    
  • method属性用于设置请求方式,是一个字符串数组,可以同时映射多个请求方式。如果当前请求地址瞒住,但是请求方式不满足条件,会返回 405 错误。当不设置该属性时,表示不以请求方式为条件,既可以匹配到任何请求方式的请求。

    @RequestMapping(value = {"/user_name","/user_names"},method={HttpMethod.GET,HttpMethod.POST})
    public void user_name() {
        // ...
    }
    

    SpringMVC 还提供了一些 @RequestMapping和请求方式结合的派生注解,@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping

    //等价与 @RequestMapping(value = {"/user_name","/user_names"},method=HttpMethod.GET)
    @PostMapping(value = {"/user_name","/user_names"})
    //等价与 @RequestMapping(value = {"/user_name","/user_names"},method=HttpMethod.POST)
    @PutMapping(value = {"/user_name","/user_names"})
    @DeleteMapping(value = {"/user_name","/user_names"})
    @PatchMapping(value = {"/user_name","/user_names"})
    public void user_name() {
        // ...
    }
    
  • params属性通过请求参数匹配请求映射,是一个字符串数组,可以同时映射多个请求参数。有下列四种表达式用于设置请求参数和请求映射的匹配关系。

    //表示必须携带 accountName 参数,不能携带 accountName2 参数
    //myParam参数的值必须为 myValue,myParam2参数的值不能为 100
    @RequestMapping(value = {"/user_name","/user_names"},method={HttpMethod.GET,HttpMethod.POST},params = {"accountName","!accountName2","myParam=myValue","myParam2!=100"})
    public void user_name() {
        // ...
    }
    

SpringMVC的工作流程只是稍作了解,不需要记忆。而给 Controller 类添加请求映射主要用于将 Controller 类中的方法与请求地址进行映射是必须要掌握的。

5、处理 PUT 和 DELETE 请求方式

由于浏览器只支持发送 GET 和 POST 方式的请求,那么当我们想要发送 PUT 和 DELETE 请求时,有两种解决方法:

  • 通过 Ajax 发送请求时设置请求方式为 PUT 或 DELETE。
  • 通过 SpringMVC 提供了 HiddenHttpMethodFilter 将 POST 请求转换为 DELETE 或 PUT 请求

那么我们主要来了解一下第二种方式:想要 HiddenHttpMethodFilter 处理 PUT 和 DELETE 请求必须满足两个条件,当前请求的请求方式必须为post和当前请求必须传输请求参数_method

在 web.xml 中注册HiddenHttpMethodFilter

<filter>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

想要发送 POST 请求且必须存在 _method 参数可以使用如下方法:

<form action="请求地址" method="post">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="提交">
form>

你可能感兴趣的:(SpringMVC,springmvc)