Spring boot实现Rest风格请求及底层原理

Rest风格的介绍

如今各大公司都是使用restful风格来定义接口,restful也是一套接口的规范,restful可以使我们的接口更加简洁、快捷高效、透明。

常见的Rest风格/CRUD
请求方式 对应属性 使用方式
GET 查询 表单请求方式为get
POST 新增 表单请求方式为post
DELETE 删除 表单请求方式为post/前段框架中发ajax请求可以为delete
PUT 修改 表单请求方式为post/前段框架中发ajax请求可以为put

很显然,这对应着我们开发中必不可少的增删改查。下面来个具体的案例来介绍一下。

Rest风格的案例

Controller层

@RestController
public class RestStyleController {


    @RequestMapping(value = "getRestStyle",method = RequestMethod.GET)
//    @GetMapping("/getRestStyle")   等价于上面代码
    public String getRestStyle(){
        return "this is getRestStyle";
    }

    @RequestMapping(value = "postRestStyle",method = RequestMethod.POST)
//    @PostMapping("/postRestStyle")    等价于上面代码
    public String postRestStyle(){
        return "this is postRestStyle";
    }

    @RequestMapping(value = "deleteRestStyle",method = RequestMethod.DELETE)
//    @DeleteMapping("/deleteRestStyle")    等价于上面代码
    public String deleteRestStyle(){
        return "this is deleteRestStyle";
    }

    @RequestMapping(value = "putRestStyle",method = RequestMethod.PUT)
//    @PutMapping("/putRestStyle")    等价于上面代码
    public String putRestStyle(){
        return "this is putRestStyle";
    }

}

 HTML代码,注意HTML文件要放在Spring boot默认扫描的静态文件夹里面,比如static等等...




    
    RestStyleTest


CRUD攻城狮

测试如下:

Spring boot实现Rest风格请求及底层原理_第1张图片

 Spring boot实现Rest风格请求及底层原理_第2张图片

 

Spring boot实现Rest风格请求及底层原理_第3张图片

 Spring boot实现Rest风格请求及底层原理_第4张图片

 测试DELETE和PUT的时候就发现报405错误了,后端控制台说当前请求不支持Post请求,不用担心我们看到源码。

Spring boot实现Rest风格请求及底层原理_第5张图片

 这里自动装配的时候给出一个条件,也就是我们的配置文件中是否配置了spring.mvc.formcontent.filter.enable是不是为true,默认是false,也就是说Spring boot并没有把支持rest风格的配置类给注入到IoC容器中,所以我们在我们的.properties或者.yaml文件中配置一下就可以了。

# 开启支持rest风格的请求
spring.mvc.hiddenmethod.filter.enabled=true   

重启一下项目。再次测试!

Spring boot实现Rest风格请求及底层原理_第6张图片

Spring boot实现Rest风格请求及底层原理_第7张图片

测试全部通过,那么下面就是源码环节!

Rest风格的底层源码

如今都是Spring boot的天下,以前传统的ssm框架+tomcat项目已经基本淘汰了,所以源码只讲解Spring boot的。

对于Spring boot来说是帮开发者减轻了大部分的配置,让开发者专注于业务层面,所以我们就往自动配置文件走,Spring boot对于自动配置是有一个规范也就是需要在MATE-INF/spring.factories中定义好自动配置的类,让Spring boot来扫描并注入到IoC容器中,所以我们在Spring boot自带的自动配置包中的spring.factories中找到WebMvcAutoConfiguration,关于Web开发的自动配置基本都在这里了。

Spring boot实现Rest风格请求及底层原理_第8张图片

Spring boot实现Rest风格请求及底层原理_第9张图片

我觉得继续往下之前,我们可以来一个推理过程:

  1. 我们可以清楚的看到自动配置的类是有Filter的踪迹,所以目测他是通过JavaWeb的过滤器来做的一些判断和修改。
  2. 我们再编写DELETE和PUT两个方式的请求的表单时候,需要写一个input来隐藏,中间有一个name标签为_method,value标签为DELETE,所以我们可以推测底层肯定是通过这个隐藏的标签的值来做的判断。

并且这里复习一下JavaWeb的过滤器。

Spring boot实现Rest风格请求及底层原理_第10张图片

 init:对过滤器做一些初始化操作

doFilter:放行操作,可以在放行前做一些自定义的事情

destroy:摧毁前的回调

Spring boot实现Rest风格请求及底层原理_第11张图片

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {

   // 获取到当前的request请求对象
   HttpServletRequest requestToUse = request;

   // 判断当前请求是否是post请求,虽然我们可能是DELETE或者是PUT但是请求方法还是POST
   if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {

      // 从request请求中获取到this.methodParam的值,这个值就是_method
      String paramValue = request.getParameter(this.methodParam);

      // 判断是否存在_method
      // 如果不存在就直接跳过这里,执行doFilter执行下一个过滤器了
      if (StringUtils.hasLength(paramValue)) {

        // 转换成大写
         String method = paramValue.toUpperCase(Locale.ENGLISH);

        // 判断是不是rest风格的参数。
         if (ALLOWED_METHODS.contains(method)) {

            // 是rest风格的就创建一个HttpMethodRequestWrapper
            // 其实HttpMethodRequestWrapper也就是一个标准的装饰器模式,套了一层而已底层还是HttpServletRequest 
            requestToUse = new HttpMethodRequestWrapper(request, method);
         }
      }
   }

    // 放行操作
   filterChain.doFilter(requestToUse, response);
}

上面代码块的大致操作:

  1. 获取到request请求对象
  2. 判断是不是post请求,因为我们定义的DELETE还是PUT最终请求方式都是post方式提交
  3. 如果是post请求就获取到我们隐藏表单的值,也就是_method的值
  4. 判断_method对应的值是不是SpringMVC支持的rest风格的值。
  5. 如果是SpringMVC支持的rest风格的值,就创建一个HttpMethodRequestWrapper对象,HttpMethodRequestWrapper也就是在原本的request上面套了一层而已。
  6. 放行,后续使用的都是HttpMethodRequestWrapper对象。

这个方法介绍完就介绍完底层了,也就是通过过滤器把请求的参数给获取到,然后封装成一个特别的request请求对象然后后续就是通过tomcat与servlet打交道,最后就到了DispatcherServlet的doDispatch方法然后就处理我们的请求。不是很懂DispatcherServlet的可以跳转下面链接学习

DispatcherServlet的初步认识icon-default.png?t=M276https://blog.csdn.net/qq_43799161/article/details/122283520?spm=1001.2014.3001.5501SpringMVC工作流程icon-default.png?t=M276https://blog.csdn.net/qq_43799161/article/details/122309958?spm=1001.2014.3001.5501

我们知道底层肯定是过滤器,但是我们是不是要考虑一下为什么会走到这个doFilterInternal重写方法来?

Spring boot实现Rest风格请求及底层原理_第12张图片

Spring boot实现Rest风格请求及底层原理_第13张图片

模板模式的学习icon-default.png?t=M276https://blog.csdn.net/qq_43799161/article/details/123635463?spm=1001.2014.3001.5501

 大致就是tomcat维护了一个过滤器链,一个一个执行,而对于SpringMVC来说实现了过滤器,所以请求一过来先进入到Tomcat,然后执行一个过滤器链(这里包括SpringMVC定义的)然后就走到OncePerRequestFilter过滤器,这类也是HiddenHttpMethodFilter父类,他其中定义了一个模板模式的模板方法,来让HiddenHttpMethodFilter子类实现逻辑,而子类也是对Rest方式接口做一个判断来对request对象做一个增强。

总结

对于Rest风格的使用来说没啥好总结的,但是对于源码来说呢。叶子->树干->整课树,所以看任何一个关于Spring系列的框架都少不了一些核心源码的支持。所以建议大家没事多去累计一些关键核心源码,因为如今JavaEE已经是Spring系列的天下了,什么都逃不过这些核心源码!博主也是一个专门写热门框架使用和源码解读的,所以可以关注一下~!

最后,如果本帖对您有一定的帮助,希望您点赞+关注+收藏,您的支持是给我最大的动力,后续一直会更新热门框架的使用和源码解读~!

你可能感兴趣的:(源码解读,Spring,MVC系列,热门框架的使用,java,后端,spring,spring,boot,mvc)