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

2023-11-18

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等等...

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RestStyleTest</title>
</head>
<body>
<h1>CRUD攻城狮</h1>
<!-- get请求 -->
<form action="/getRestStyle" method="get">
  <input type="submit" value="get查询请求">
</form>

<!-- post请求 -->
<form action="/postRestStyle" method="post">
  <input type="submit" value="post增加请求">
</form>

<!-- delete请求 -->
<form action="/deleteRestStyle" method="post">
    <input type="hidden" name="_method" value="DELETE">
    <input type="submit" value="delete删除请求">
</form>

<!-- put请求 -->
<form action="/putRestStyle" method="post">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="put修改请求">
</form>
</body>
</html>

测试如下:

 

 

 

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

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

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

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

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

Rest风格的底层源码

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

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

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

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

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

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

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

destroy:摧毁前的回调

@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重写方法来?

模板模式的学习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系列的天下了,什么都逃不过这些核心源码!博主也是一个专门写热门框架使用和源码解读的,所以可以关注一下~!

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring boot实现Rest风格请求及底层原理 的相关文章

随机推荐

  • csgo修改服务器时间,csgo热身时间参数指令 热身时间怎么改

    反恐精英 全球攻势 简称CS GO 是一款由VALVE与Hidden Path Entertainment合作开发的第一人称射击游戏 游戏中可以更改相关控制命令 下面带来csgo热身时间参数指令 热身时间怎么改方法 csgo热身时间参数指令
  • 多系统集成:vue大型项目之分模块运行/打包

    本文以vue cli3 为例 实现多系统集成下的分模块打包 分模块打包方式多种多样 下文可适用于多系统之间互不干扰 主系统可集成各子系统 各子系统又可单独运行的业务场景 一 目标 我们要实现什么 所谓分模块打包 那么各个模块内就必须得有自己
  • 使用Arthas排查问题

    简介 Arthas 是Alibaba开源的Java诊断工具 深受开发者喜爱 当你遇到以下类似问题而束手无策时 Arthas可以帮助你解决 这个类从哪个 jar 包加载的 为什么会报各种类相关的 Exception 我改的代码为什么没有执行到
  • ThreadLocal详解

    如果有兴趣了解更多相关内容 欢迎来我的个人网站看看 瞳孔空间 一 基本介绍 ThreadLocal类能提供线程内部的局部变量 这种变量在多线程环境下访问时能保证各个线程的变量相对独立于其他线程内的变量 ThreadLocal实例通常来说都是
  • 关于java.lang.UnsatisfiedLinkError的小案例

    在许多项目中我们都会用到第三方动态库 so文件 但是往往会引来很多烦恼 比如 java lang UnsatisfiedLinkError 06 17 15 52 08 097 7876 7916 com ishow scan E Andr
  • 前端js和jq中select下拉框

    获取select选中的option的值 ddlRegType find option selected val 获取select选中的text ddlRegType find option selected text 获取select选中的
  • 03-postgresql报错ERROR: operator does not exist: numeric = character varyin

    现在要把数据库换成postgresql 但在转换过程中发现postgresql对传入的参数类型匹配相当严格 如select from user where a b 假设a类型为numeric 而传入的b为string的话postgresql
  • wifi类物联产品配网前言

    文章目录 1 SmartConfig配网 仅支持2 4G 2 web方式配网 3 一键配网 BLE 传统蓝牙和wifi 3 1 BLE方式 3 2 传统蓝牙方式 3 3 wifi方式 3 4 4G 网口或其他直连设备 3 5 其他配网方式
  • Linux 以root用户登录无法启动VSCode

    Linux 以root用户登录无法启动VSCode 环境 Ubuntu18 04 VSCode 复现 以root用户登录Ubuntu后单机VSCode图标打开VSCode BUG 无法打开VSCode 原因 VSCode默认不允许以root
  • vc扩展名

    APS 存放二进制资源的中间文件 VC把当前资源文件转换成二进制格式 并存放在APS文件中 以加快资源装载速度 资源辅助文件 BMP 位图资源文件 BSC 浏览信息文件 由浏览信息维护工具 BSCMAKE 从原始浏览信息文件 SBR 中生成
  • NoSql的四大类型

    NoSQL Not Only Sql 泛指非关系型的数据库 区别于关系数据库 它们不保证关系数据的ACID特性 NoSQL是一项全新的数据库革命性运动 其拥护者们提倡运用非关系型的数据存储 相对于铺天盖地的关系型数据库运用 这一概念无疑是一
  • 【扩散模型】3、DDIM

    文章目录 一 背景 二 DDIM 如何改进 2 1 DDPM 的原理回顾 2 2 DDIM 的非马尔科夫前向扩散过程 2 3 非马尔科夫扩散逆过程的采样 2 4 加速采样 Respacing 三 效果 论文 Denoising Diffus
  • 3D CG软件blender入门教程:手把手教你使用方法

    翻译 BeforeDawn大家好 我是bpm 目前在做一些设计师与技术总监相关的工作 这篇文章主要以blender这个软件作为切入点来为大家讲解一下3D CG软件blender相关概要以及使用的方法 blender是什么那么 大家知道这个名
  • 【Matlab】LM迭代估计法

    简介 在最近的传感器校准算法学习中 有一些非线性的代价函数求解使用最小二乘法很难求解 使用LM算法求解会简单许多 因此学习了一下LM算法的基础记录一下 LM 优化迭代算法时一种非线性优化算法 可以看作是梯度下降与高斯牛顿法的结合 综合了两者
  • 301跳转:http跳转https不带www跳转到带www

    写在 htaccess中 一 http跳转https RewriteCond SERVER PORT 443 RewriteRule https SERVER NAME 1 R 301 L 二 不带www跳转到带www RewriteCon
  • shell脚本-统计字符串中数字字母的个数

    bin bash read p 请输入一个字符串 str count1 0 count2 0 count3 0 count4 0 num str num for i in seq 0 num do ch str i 1 echo n ch
  • Mac 不小心断开移动硬盘导致磁盘无法读取和加载(顺利解决!)

    目录 1 问题 2 解决 2 1 终端中执行 diskutil list 2 2 输入 sudo diskutil mount dev disk0 disk1 disk2 同理 情况一 情况二 情况三 1 问题 不小心碰到USB插口 导致无
  • iOS证书(.p12)和描述文件(.mobileprovision)申请

    我们在做uniapp开发的时候 打包ios应用需要自有证书 而自有证书包含 p12和 mobileprovision这两个跟证书有关的文件 但是uniapp官方的教程 却是需要使用苹果mac系统去申请 假如没有mac电脑 则它的教程就没有参
  • Python pass 语句

    Python pass 是空语句 是为了保持程序结构的完整性 pass 不做任何事情 一般用做占位语句 Python 语言 pass 语句语法格式如下 pass 测试实例 usr bin python coding UTF 8 输出 Pyt
  • Spring boot实现Rest风格请求及底层原理

    Rest风格的介绍 如今各大公司都是使用restful风格来定义接口 restful也是一套接口的规范 restful可以使我们的接口更加简洁 快捷高效 透明 常见的Rest风格 CRUD 请求方式 对应属性 使用方式 GET 查询 表单请