0%

SpringBoot—Web·Rest使用与原理

这里记录了Web开发中请求映射 @xxxMapping 注解的使用。在表单中通过Rest风格发送 GET、POST、PUT、DELETE 请求的方法。以及实现表单中Rest功能的 HiddenHttpMethodFilter 的原理。特别注意的是,要想在表单使用 Rest风格 发送请求,需要手动开启HiddenHttpMethodFilter。

涉及:请求映射相关:@RequestMapping、@GetMapping、@PostMapping、@DeleteMapping、@PutMapping。以及 html 中表单使用 Rest 的编写示例。

请求映射

接收请求处理的最先的操作是请求映射。请求映射注解格式是:@xxxMapping
常用的请求映射注解:

1
2
3
4
5
6
7
8
9
@RequestMapping(value = "/user",method = RequestMethod.GET)
value = "请求映射的值" method = "请求方法"

还有一些简化的注解可以代表不同请求方法
@GetMapping("/user")
@PostMapping("/user")
@PutMapping("/user")
@DeleteMapping("/user")

Rest风格用法

Rest风格概述

Rest风格支持指——使用HTTP请求方式动词来表示对资源的操作,不需要改变URL路径
Rest风格操作方法:
/user –> GET-获取用户、DELETE-删除用户、PUT-修改用户、POST-保存用户

Rest表单中的实现

实现方法
因为表单只能传入 post 和 get 请求,所以需要利用核心Filter:HiddenHttpMethodFilter 实现重写请求。
具体原理见下面的原理分析。
用法

  • SpringBoot中手动开启HiddenHttpMethodFilter

    1
    2
    3
    4
    5
    spring:
    mvc:
    hiddenmethod:
    filter:
    enabled: true #开启页面表单的Rest功能
  • html表单中
    GET 和 POST 请求可以直接发出;
    DELETE 和 PUT 请求需要使用隐藏参数
    设置:①表单 method=post,②隐藏域 _method = put

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    测试REST风格
    =============== GET & POST ================
    <form action="/user" method="get">
    <input value="REST-GET 提交" type="submit"/>
    </form>
    <form action="/user" method="post">
    <input value="REST-POST 提交" type="submit"/>
    </form>

    =============== DELETE & PUT ================
    <form action="/user" method="post">
    <input name="_method" type="hidden" value="delete"/>
    <input value="REST-DELETE 提交" type="submit"/>
    </form>
    <form action="/user" method="post">
    <input name="_method" type="hidden" value="PUT"/>
    <input value="REST-PUT 提交" type="submit"/>
    </form>
  • Controller类测试写法:
    写好相关方法的请求映射即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ......略
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    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-张三";
    }
    ......略

使用客户端工具发送请求

使用客户端工具,如PostMan直接发送Put、delete等方式请求,无需Filter。
因为可以直接发出各类请求。而拦截器只会拦截POST

Rest用法原理

为什么需要在yaml手动开启

我们看OrderedHiddenHttpMethodFilter源码,重点在第3行:

绑定配置中前缀 spring.mvc.hiddenmethod.filterenable 参数。当这个参数是 true 才生效。如果没配,视为false

1
2
3
4
5
6
7
8
9
10
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)

//重点:
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
//
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}

HiddenHttpMethodFilter 工作流程

表单提交要使用REST的时候,以PUT为例:

  • 表单提交会带上_method=PUT
  • 请求过来被HiddenHttpMethodFilter拦截
  • HiddenHttpMethodFilter判断请求是否正常,并且是POST
    • 获取到_method的值。
    • 兼容以下请求;PUT.DELETE.PATCH
    • 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
    • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。