Rest-优雅的url 请求风格

简介: Rest-优雅的url 请求风格

Rest-优雅的url 请求风格


Rest-基本介绍


  1. 1、REST:即Representational State Transfer。(资源)表现层状态转化。是目前流行的请求方式。它结构清晰, 很多网站采用
  2. 2、HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。


它们分别对应四种基本操作

GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。


  1. 3、实例
    传统的请求方法:
    getBook?id=1 GET
    delete?id=1 GET
    update POST
    add POST


  1. 4、说明: 传统的url 是通过参数来说明crud 的类型,rest 是通过get/post/put/delete 来说明crud 的类型.


REST 的核心过滤器


当前的浏览器只支持post/get 请求,因此为了得到put/delete 的请求方式需要使用Spring提供的HiddenHttpMethodFilter 过滤器进行转换.


1HiddenHttpMethodFilter:浏览器form 表单只支持GET 与POST 请求,而DELETE、PUT等method 并不支持,


Spring 添加了一个过滤器,可以将这些请求转换为标准的http 方法,使得支持GET、POST、PUT 与DELETE 请求。


2HiddenHttpMethodFilter 能对post 请求方式进行转换,因此我们需要特别的注意这一点。


3这个过滤器需要在web.xml 中配置。


Rest 风格的url-完成增删改查


Rest 应用案例-代码实现


修改web.xml 添加HiddenHttpMethodFilter

 <!--配置HiddenHttpMethodFilter
    1. 把 以post方式提交的delete和put请求进行转换
    2. 配置url-pattern 是 /* 表示所有请求都经过 hiddenHttpMethodFilter过滤
    3. 后面可以debug源码,看的很清楚
    -->
    <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>


修改springDispatcherServlet-servlet.xml

<!-- 加入两个常规配置-->
<!-- 能支持SpringMVC 高级功能,比如JSR303 校验,映射动态请求-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 将SpringMVC 不能处理的请求交给Tomcat, 比如请求css,js 等-->
<mvc:default-servlet-handler/>


创建springmvc\web\rest.jsp, 注意需要引入jquery, 测试的时候查询/添加/删除/修改一个一个来.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>rest </title>
<%--    引入jquery--%>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        $(function () { //当页面加载完成后,就执行
            //给删除超链接绑定一个点击事件
            $("#deleteBook").click(function (){
                //我们自己定义给提交的行为
                $("#hiddenForm").attr("action", this.href);
                $(":hidden").val("DELETE");
                $("#hiddenForm").submit();//这里就是提交删除请求了
    //这里必须返回false,否则会提交两次
                return false; //改变点击超链接的行为, 不在提交
            })
        })
    </script>
</head>
<body>
    <h3>Rest风格的crud操作案例</h3>
    <br><hr>
    <h3>rest风格的url 查询书籍[get]</h3>
    <a href="user/book/200">点击查询书籍</a>
    <br><hr>
    <h3>rest风格的url 添加书籍[post]</h3>
    <form action="user/book" method="post">
        name:<input name="bookName" type="text"><br>
        <input type="submit" value="添加书籍">
    </form>
    <br><hr>
    <h3>rest风格的url, 删除一本书</h3>
    <%--
        1. 默认情况下 <a href="user/book/600">删除指定id的书</a> 是get
        2. 怎么样将 get 请求转成 springmvc 可以识别的 delete 就要考虑HiddenHttpMethodFilter机制
           public static final String DEFAULT_METHOD_PARAM = "_method";
           ---------------------------------------------------
           private static final List<String> ALLOWED_METHODS =
                    Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
                            HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
          ---------------------------------------------------
           if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
                    String paramValue = request.getParameter(this.methodParam);
                    if (StringUtils.hasLength(paramValue)) {
                        String method = paramValue.toUpperCase(Locale.ENGLISH);
                        if (ALLOWED_METHODS.contains(method)) {
                            requestToUse = new HttpMethodRequestWrapper(request, method);
                        }
                    }
                }
        3. 上面代码可以看到 HiddenHttpMethodFilter 过滤器可以对以Post方式提交的delete,put,patch进行转换,成springmvc
           识别的 RequestMethod.DELETE / RequestMethod.PUT /...
        4. 我们需要将 get <a href="user/book/600">删除指定id的书</a> 以post方式提交给后端handler, 这样过滤器才会生效
        5. 我们可以用jquery来处理-引入jquery
    --%>
    <a href="user/book/600" id="deleteBook">删除指定id的书</a>
    <form action="" method="post" id="hiddenForm">
        <input type="hidden" name="_method"/>
    </form>
    <br><hr>
    <h3>rest风格的url 修改书籍[put]~</h3>
    <form action="user/book/666" method="post">
        <input type="hidden" name="_method" value="PUT">
        <input type="submit" value="修改书籍~">
    </form>
</body>
</html>


创建com\web\rest\BookHandler.java , 处理rest 风格的请求
```java
@RequestMapping("/user")
@Controller
public class BookHandler {
    //查询[GET]
    @RequestMapping(value = "/book/{id}", method = RequestMethod.GET)
    public String getBook(@PathVariable("id") String id) {
        System.out.println("查询书籍 id=" + id);
        return "success";
    }
    //添加[POST]
    @PostMapping(value = "/book")
    public String addBook(String bookName) {
        System.out.println("添加书籍 bookName== " + bookName);
        return "success";
    }
    //删除[DELETE]
    @RequestMapping(value = "/book/{id}", method = RequestMethod.DELETE)
    public String delBook(@PathVariable("id") String id) {
        System.out.println("删除书籍 id= " + id);
        //return "success"; //[如果这样返回会报错 JSPs only permit GET POST or HEAD]
        //1. redirect:/user/success重定向
        //2. 会被解析成 /springmvc/user/success
        return "redirect:/user/success";
    }
    //如果请求是 /user/success , 就转发到 success.jsp
    //successGenecal对应的url http://ip:port/springmvc/user/success
    @RequestMapping(value = "/success")
    public String successGenecal() {
        return "success";  //由该方法 转发到success.jsp页面
    }
    //修改[PUT]
    @PutMapping(value = "/book/{id}")
    public String updateBook(@PathVariable("id") String id) {
        System.out.println("修改书籍 id=" + id);
        return "redirect:/user/success";
    }
}


注意事项和细节说明


1HiddenHttpMethodFilter 在将post 转成delete / put 请求时,是按_method 参数名来读取的。


2如果web 项目是运行在Tomcat 8 及以上,会发现被过滤成DELETE 和PUT 请求,到达控制器时能顺利执行,


但是返回时(forward)会报HTTP 405 的错误提示:消息JSP 只允许GET、POST 或HEAD。


解决方式1: 使用Tomcat7


解决方式2: 将请求转发(forward)改为请求重定向(redirect):重定向到一个Handler,由Handler 转发到页面


image.png

  1. 3页面测试时, 如果出现点击修改书籍,仍然走的是删除url ,是因为浏览器原因(缓存等原因), 换成chrome 即可
相关文章
|
3月前
feign发起url请求日期序列化问题
feign发起url请求日期序列化问题
43 0
|
4月前
Copy网页中F12里的请求url到postman,并且把所有参数都带过来
Copy网页中F12里的请求url到postman,并且把所有参数都带过来
29 0
|
5月前
|
Web App开发 JavaScript Java
教会你什么是Spring-Rest- url 请求风格
教会你什么是Spring-Rest- url 请求风格
50 0
POST 请求出现异常!java.io.IOException: Server returned HTTP response code: 400 for URL
POST 请求出现异常!java.io.IOException: Server returned HTTP response code: 400 for URL
900 0
|
7月前
|
Web App开发 资源调度 开发者
SAP Fiori Elements 应用 OData 元数据请求 url 里的模型名称决定逻辑
SAP Fiori Elements 应用 OData 元数据请求 url 里的模型名称决定逻辑
49 0
|
7月前
|
存储 JavaScript 前端开发
SAP UI5 OData 请求 url 中的参数 sap-value-list=none
SAP UI5 OData 请求 url 中的参数 sap-value-list=none
33 0
|
7月前
|
Web App开发 JSON 数据格式
使用 http-proxy 代理 HTTP 请求时遇到的 the requested url is invalid 错误消息
使用 http-proxy 代理 HTTP 请求时遇到的 the requested url is invalid 错误消息
106 0
|
8月前
|
JSON 算法 API
阿里云 OpenAPI 中,一般情况下请求参数是放在请求的 URL 中的
阿里云 OpenAPI 中,一般情况下请求参数是放在请求的 URL 中的
101 1
|
11月前
|
测试技术
【解决方案 十】判断URL请求是否成功并检测访问效率
【解决方案 十】判断URL请求是否成功并检测访问效率
181 0
|
11月前
|
测试技术 应用服务中间件 网络安全
接口测试中请求URL管理的正确姿势
接口测试中,必不可少的第一个要素就是请求URL。如何进行URL管理是接口测试的首要任务。