• Spring Boot之请求方式与请求映射过程分析


    请求方式

    Spring Boot支持Rest风格:使用HTTP请求方式的动词来表示对资源的操作

    非Rest风格

    以前这样写接口:

    /getUser   获取用户    
    /deleteUser 删除用户    
    /updateUser  修改用户      
    /saveUser 保存用户
    
    • 1
    • 2
    • 3
    • 4
    	@RequestMapping(value = "/getUser", method = RequestMethod.GET)
        public String getUser() {
            return "GET";
        }
    
        @RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
        public String deleteUser() {
            return "POST";
        }
        
        @RequestMapping(value = "/updateUser", method = RequestMethod.POST)
        public String updateUser() {
            return "POST";
        }
        
        @RequestMapping(value = "/saveUser", method = RequestMethod.POST)
        public String saveUser() {
            return "POST";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用Rest风格

    使用Rest风格,则这样写接口:

     /user    GET-获取用户    DELETE-删除用户     PUT-修改用户      POST-保存用户
    
    • 1
        @GetMapping("/user")
        public String getUser() {
            return "GET";
        }
    
        @PostMapping("/user")
        public String saveUser() {
            return "POST";
        }
    
        @PutMapping("/user")
        public String putUser() {
            return "PUT";
        }
    
        @DeleteMapping("/user")
        public String deleteUser() {
            return "DELETE";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    表单提交

    通过表单方式提交请求,请求类型只能支持Get与Post

    若表单提交要使用REST风格,则表单请求方式使用Post,添加隐藏域 _method=put_method=delete方式来支持Rest风格

    示例如下

    <form action="/user" method="post">
    	<input name="_method" type="hidden" value="delete"/>
        <input value="REST提交" type="submit"/>
    </form>
    
    • 1
    • 2
    • 3
    • 4

    SpringBoot配置文件中开启页面表单的Rest功能

    spring:
      mvc:
        hiddenmethod:
          filter:
            enabled: true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    过程分析

    首先是从自动配置类WebMvcAutoConfiguration开始,其中的hiddenHttpMethodFilter方法入手,请求首先被该方法拦截

    接着创建OrderedHiddenHttpMethodFilter对象,其又继承HiddenHttpMethodFilter
    在这里插入图片描述
    HiddenHttpMethodFilter中的doFilterInternal核心方法进行了相关拦截操作,要求是Post请求并且请求正常,然后获取请求参数_method
    在这里插入图片描述

    request.getParameter(this.methodParam)从请求中获取_method参数进行判断拦截,故可修改默认_method,自定义隐藏参数。

       @Bean
        public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
            HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
            methodFilter.setMethodParam("_mymethod");
            return methodFilter;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请求映射过程分析

    首先一个请求肯定会经过HttpServlet类的doGet()doPost()等方法,当然不一定会执行,但其子类肯定会有对其的具体实现,其实现类如下:

    在这里插入图片描述
    推测+大概看源码得出Spring Boot的一个请求会经过FrameworkServlet类的doGet()方法
    在这里插入图片描述
    processRequest方法又调用了doService方法
    在这里插入图片描述
    doService方法是一个接口,FrameworkServlet并没有具体实现
    在这里插入图片描述
    不过DispatcherServlet对其经行了具体实现,doService方法中又调用doDispatch核心请求分发方法
    在这里插入图片描述
    doDispatch方法中又寻找当前请求使用哪个Handler(处理器映射器)
    在这里插入图片描述
    Spring Boot默认已配置有如下5种处理器映射器。这里会挨个尝试所有的HandlerMapping看是否有匹配的请求
    在这里插入图片描述
    在Spring Boot启动时,相关处理器映射器已经将请求关系进行了绑定,保存了所有@RequestMapping 和handler的映射规则

    如下:某Controller层的/index请求方法就与RequestMappingHandlerMapping进行了关联绑定
    在这里插入图片描述
    接着再执行mapping.getHandler(request)
    在这里插入图片描述
    执行this.getHandlerInternal(request),来到AbstractHandlerMethodMapping类重写的方法
    在这里插入图片描述
    执行 super.getHandlerInternal(request);得到当前请求Path
    在这里插入图片描述
    执行this.lookupHandlerMethod(lookupPath, request);进行判断当前请求的是具体那个方法,即请求对应的handler,找到后并返回。
    在这里插入图片描述

    到此,Spring Boot的请求映射过程解析完毕。最终,请求映射过程中涉及的类如下:
    在这里插入图片描述

  • 相关阅读:
    Linux开发板(树莓派)和服务器进行双向通信(socket)
    128.(前端)增加商品前数据处理——将二维数组转成字符串形式传递
    python149基于知识图谱的智能推荐系统(flask)复现
    基于Spring Boot和Spring Cloud实现微服务架构学习(四)-Spring Cloud总结
    Filter与Listener(过滤器与监听器)
    批量重命名与翻译文件技巧大揭秘
    Java并发编程:如何正确使用 volatile、synchronized 和 final 关键字
    骨传导耳机怎么听到声音?骨传导耳机是否会对听力造成损害?
    第七十天 c++perimer70~115string类型总结
    STC51单片机27——控制无刷电机
  • 原文地址:https://blog.csdn.net/qq_38628046/article/details/108592963