SpringBoot中的Restful风格

1. 什么是Restful?

  1. RESTful架构风格是目前最流行的一种架构风格,它机构清晰、符合标准、易于理解、扩展方便,所以在Web开发中经常被使用。
    REST,全称是Representational State Transfer,译作“表现层状态转化”,在 2000 年 Roy Fielding 的博士论文中首次被提出。面向资源是REST明显的特征,对于同一个资源的一组不同的操作。资源是服务器 上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。REST要求必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。
  2. 代码:
/**
 * 如下代码实现了对一组路径的
 * put delete get post patch方法
 * 让我们代码看起来更加简介,提高了对同一个路径的复用性
 * 以下对同一个资源都可以用 /user/{id}实现
 * 比起 /usr/del/{id} /usr/update/{id} /user/get/{id} 要简洁许多
 */
@RestController
@Slf4j
@RequestMapping("/user")
public class ConfigurationController{

    @PutMapping("/{id}")
    public String putUser(@PathVariable("id") String id){
        return "Update Id:" + id;
    }

    @DeleteMapping("/{id}")
    public String delUser(@PathVariable("id") String id){
        return "Delete Id:" + id;
    }

    @PostMapping("/{id}")
    public String postUser(@PathVariable("id") String id){
        return "Post Id:" + id;
    }

    @GetMapping("/{id}")
    public String getUser(@PathVariable("id") String id){
        return "Get Id:" + id;
    }
    //与Put不同Patch表示更新部分资源
    @PatchMapping("{id}")
    public String patch(@PathVariable("id") String id){
        return "Patch Id:" + id;
    }
    

}

2.SpringBoot是如何实现restful的?

  1. 其原理是在表单提交时配置了一个隐藏域_method=put
<input name="_method" type="hidden" vlaue="put"/>
<input value="RestFul-Put提交" type="submit"/>
  1. 我们需要手动开启SpringBoot中的HiddenHttpMethodFilter
	@Bean
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)//这里matchIfMissing如果没有开启的话默认为false
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
		return new OrderedHiddenHttpMethodFilter();
	}
  1. 我们来看一下这个HiddenHttpMethodFilter发现其中有个拦截器
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取请求
        HttpServletRequest requestToUse = request;
        //判断是否是post请求并且没有错误(这里也反应了其实put delete patch这些都是post的衍生)
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
            //这里的this.methodParam 是类中的属性 private String methodParam = "_method";
            //这是默认的隐藏域参数_method 获取对应的value put
            String paramValue = request.getParameter(this.methodParam);
            //判断是否为空
            if (StringUtils.hasLength(paramValue)) {
                //这里同义转换为大写,证明前端大小写都是可以的
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                //如果允许的方法里包含此方法对其进行包装
                //这个属性是一个静态常量 初始化时传入如下方法
                if (ALLOWED_METHODS.contains(method)) {
                    //装饰器将我们的请求进行包装
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }
        //初始化允许的方法
  static {
      //看到一共 put delete patch三种方法
        ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
    }
  1. 装饰器,过滤后会为我们的请求包装为 put delete patch 好与@xxxMapping对应转换

    //其是HiddenHttpMethodFilter中的一个内部类
    //可以看到继承于HttpServletRequestWrapper而HttpServletRequestWrapper又继承于
    //ServletRequestWrapper
    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
            private final String method;
    
            public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
                super(request);
                //其作用就是将method写为我们传入的method
                this.method = method;
            }
    
            public String getMethod() {
                //其作用就是将method写为我们传入的method
                return this.method;
            }
        }
    

3.使用客户端工具

  1. postman,restfultools等客户端请求工具无需开启有隐藏域,因为其在发出请求时就已经是put,delete,patch

    不会通过我们的过滤器

  2. 所以这个隐藏域只针对于无法发出这些请求的表单

  3. springboot项目开启隐藏域

    spring:
      mvc:
        hiddenmethod:
          filter:
            enabled: true
    

4. 改变默认隐藏域参数

@Bean
//我们发现SpringBoot是在缺少HiddenHttpMethodFilter这个类时才会去为我们装配这个系统默认的HiddenHttpMethodFilter,同理那我们可以自己自定义配置一个
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)//这里matchIfMissing如果没有开启的话默认为false
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
	return new OrderedHiddenHttpMethodFilter();
}
  1. 代码如下:
@Configuration
public class MyConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        hiddenHttpMethodFilter.setMethodParam("_m");
        return hiddenHttpMethodFilter;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值