前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring-REST风格-源码解析

Spring-REST风格-源码解析

作者头像
程序员阿杜
发布2021-07-28 10:16:55
3550
发布2021-07-28 10:16:55
举报
文章被收录于专栏:开源君开源君

Spring-REST风格-源码解析

文章已同步至GitHub开源项目: Java超神之路

SpringBoot支持的RESTful风格的请求方式,底层是如何实现的呢?

准备

  • html
代码语言:javascript
复制
<form action="/user" method="POST">
    <input name="_method" hidden value="DELETE">
    <input type="submit" value="DELETE提交 删除用户信息">
</form>
  • Controller
代码语言:javascript
复制
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
        return "DELETE-删除用户";
    }

开始Debug

  • 表单提交会带上**_method=PUT**
代码语言:javascript
复制
<form action="/user" method="POST">
    <input name="_method" hidden value="DELETE">
    <input type="submit" value="DELETE提交 删除用户信息">
</form>
  • 通过Debug发现,请求过来被HiddenHttpMethodFilter拦截
代码语言:javascript
复制
// 拦截所有请求
@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		HttpServletRequest requestToUse = request;

        //请求是否有错误,并且是POST
		if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) { 
            //获取到名称为`this.methodParam`的参数
			String paramValue = request.getParameter(this.methodParam); 
            //如果有这个参数
			if (StringUtils.hasLength(paramValue)) {
                //转化为英文大写 DELETE
				String method = paramValue.toUpperCase(Locale.ENGLISH); //获取到_method的值。
				if (ALLOWED_METHODS.contains(method)) { //如果是允许的值
                    //将之前的原生请求中的请求方式改为参数_method的请求方式
					requestToUse = new HttpMethodRequestWrapper(request, method); //包装 
				}
			}
		}

        //将包装好的请求放行。
		filterChain.doFilter(requestToUse, response); 
	}

开始Debug

通过DeBug我们发现,首先请求进来,会if判断是否是POST请求,并且请求中没有错误。之后用request.getParameter方法获取到名称为this.methodParam的参数。我们发现,this.methodParam的值为_mothod

image-20210726144142519
image-20210726144142519

所以获取到了请求中参数名称为_method的值。DELETE

image-20210726143515937
image-20210726143515937

然后通过String method = paramValue.toUpperCase(Locale.ENGLISH);转换为大写。之后判断是包含在否是允许的请求中。通过Debug,允许的请求如下

image-20210726144219958
image-20210726144219958

也就是说兼容以下请求;PUT.DELETE.PATCH

之后会重新创建一个HttpMethodRequestWrapper请求。

这个类支持了请求传参。将原生的请求方式改为传递过来的参数DELETE

代码语言:javascript
复制
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
			super(request);
			this.method = method;
		}
image-20210726145110249
image-20210726145110249

将包装好的请求放行。

代码语言:javascript
复制
filterChain.doFilter(requestToUse, response);

此时,原生的请求由POST方法改为参数_method中指定的请求类型。然后由Controller层接收。

文章已同步至GitHub开源项目: Java超神之路 更多Java相关知识,欢迎访问!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring-REST风格-源码解析
    • 准备
      • 开始Debug
        • 开始Debug
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档