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开发的自动配置基本都在这里了。
我觉得继续往下之前,我们可以来一个推理过程:
- 我们可以清楚的看到自动配置的类是有Filter的踪迹,所以目测他是通过JavaWeb的过滤器来做的一些判断和修改。
- 我们再编写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);
}
上面代码块的大致操作:
- 获取到request请求对象
- 判断是不是post请求,因为我们定义的DELETE还是PUT最终请求方式都是post方式提交
- 如果是post请求就获取到我们隐藏表单的值,也就是_method的值
- 判断_method对应的值是不是SpringMVC支持的rest风格的值。
- 如果是SpringMVC支持的rest风格的值,就创建一个HttpMethodRequestWrapper对象,HttpMethodRequestWrapper也就是在原本的request上面套了一层而已。
- 放行,后续使用的都是HttpMethodRequestWrapper对象。
这个方法介绍完就介绍完底层了,也就是通过过滤器把请求的参数给获取到,然后封装成一个特别的request请求对象然后后续就是通过tomcat与servlet打交道,最后就到了DispatcherServlet的doDispatch方法然后就处理我们的请求。不是很懂DispatcherServlet的可以跳转下面链接学习
DispatcherServlet的初步认识https://blog.csdn.net/qq_43799161/article/details/122283520?spm=1001.2014.3001.5501SpringMVC工作流程https://blog.csdn.net/qq_43799161/article/details/122309958?spm=1001.2014.3001.5501
我们知道底层肯定是过滤器,但是我们是不是要考虑一下为什么会走到这个doFilterInternal重写方法来?
模板模式的学习https://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系列的天下了,什么都逃不过这些核心源码!博主也是一个专门写热门框架使用和源码解读的,所以可以关注一下~!
最后,如果本帖对您有一定的帮助,希望您点赞+关注+收藏,您的支持是给我最大的动力,后续一直会更新热门框架的使用和源码解读~!