REST风格的URL地址约束

一、REST风格

REST即 Representational State Transfer。(资源)表现层状态转化,是目前最流行的一种互联网软件架构。

  • 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。获取这个资源,访问它的URI就可以,因此URI即为每一个资源的独一无二的识别符
  • 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
  • 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。

REST风格的URL地址:请求方式来区分操作
在这里插入图片描述

二、REST风格的增删改查

SpringMVC中有一个Filter,可以把普通的请求转化为规定形式的请求,首先配置这个Filter

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

需要在发送POST请求时携带一个 name="_method"的隐含域,值为PUTDELETE

<a href="book/1">查询图书</a><br/>

  <form action="book" method="post">
    <input type="submit" value="添加1号图书"/>
  </form><br/>

<%--发送DELETE请求--%>
<form action="book/1" method="post">
  <input type="hidden" name="_method" value="DELETE"/>
  <input type="submit" value="删除1号图书"/>
</form><br/>

<%--发送PUT请求--%>
<form action="book/1" method="post">
  <input type="hidden" name="_method" value="PUT"/>
  <input type="submit" value="更新1号图书"/>
</form><br/>

Controller


    @RequestMapping(value = "/book/{id}",method = RequestMethod.GET)
    public String testRESTGet(@PathVariable("id") Integer id){
        System.out.println("testRESTGet id:" + id);
        return "success";
    }

    @RequestMapping(value = "/book",method = RequestMethod.POST)
    public String testRESTPost(){
        System.out.println("testRESTPost");
        return "success";
    }

    @RequestMapping(value = "/book/{id}",method = RequestMethod.PUT)
    public String testRESTPut(@PathVariable("id") Integer id){
        System.out.println("testRESTPut id:" + id);
        return "success";
    }

    @RequestMapping(value = "/book/{id}",method = RequestMethod.DELETE)
    public String testRESTDelete(@PathVariable("id") Integer id){
        System.out.println("testRESTDelete id:" + id);
        return "success";
    }

输出结果:
在这里插入图片描述

三、HiddenHttpMethodFilter过滤器源码分析

通过重写getMethod()方法实现

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
        	//获取表单上_method带来的值
            String paramValue = request.getParameter(this.methodParam);
            if (StringUtils.hasLength(paramValue)) {
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                if (ALLOWED_METHODS.contains(method)) {
                	//new了一个HttpMethodRequestWrapper对象,重写getMethod()
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);			
                }
            }
        }
		
        filterChain.doFilter((ServletRequest)requestToUse, response);
    }
    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
        private final String method;

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
            super(request);
            this.method = method;
        }
		//重写了getMethod(),得到put或者delete
        public String getMethod() {
            return this.method;
        }
    }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值