REST(Representational State Transfer)即 表述性转移,是目前最流行的一种软件架构风格
REST指的是一组架构 约束条件 和 原则 。满足这些约束条件和原则的应用程序或设计就是RESTful
REST特性:
资源(Resources): 互联网所有的事物都可以被抽象为资源 。它可以是一段文本、一张图片、一首歌 曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应 一个特性的URI。要获取这个资源,访问它的URI就可以,因此URI即为每一个资源的独一无二的识别符
PS: URI,统一资源标志符,表示的是web上每一种可用的资源表现层(Representation): 把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文 本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式
状态转换(State Transfer): 每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议, 是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转换”(State Transfer)。而这种转换是建立在表现层之上的,所以就是“表现层状态转换”
REST URL请求形式
使用 URL 表示资源时,每个资源都用一个独一无二的 URL 来表示,并使用 HTTP 方法表示操作,即准确描述服务器对资源的处理动作(GET、POST、PUT、DELETE),实现资源的增删改查
请求类型 | 说明 |
---|---|
GET | 获取资源 |
PSOT | 创建资源 |
PUT | 更新资源 |
DELETE | 删除资源 |
传统URL 与 REST风格的 URL 区别
传统URL | REST风格URL | 资源操作方式 |
---|---|---|
http://localhost:8080/getUser.do?id=12 | GET:http://localhost:8080/user/12 | 获取用户信息 |
http://localhost:8080/saveUser.do | POST:http://localhost:8080/user | 新建用户信息 |
http://localhost:8080/updateUser.do?=12 | PUT:http://localhost:8080/user/12 | 更新用户信息 |
http://localhost:8080/deleteUser.do?=12 | DELETE:http://localhost:8080/user/12 | 删除用户信息 |
REST应用
应用前提&注意:
- 添加 过滤器
org.springframework.web.filter.HiddenHttpMethodFilter
指定 请求 or 所有请求- PUT 和 DELETE 请求类型 需要以POST请求 添加
_method
属性 值为 指定的 请求类型
web.xml
配置过滤器 HiddenHttpMethodFilter
<!-- HiddenHttpMethodFilter过滤器可以将POST请求转化为put请求和delete请求! --> <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>
rest.jsp
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <script src="/js/jquery-1.11.1.js"></script> <html> <head> <title>REST风格</title> </head> <body> <h1>REST风格 URL 测试</h1> <h2>普通请求 测试</h2> <h3>get请求</h3> <a href="/rest/12">Get</a> <h3>post请求</h3> <form action="/rest/12" method="post"> <input type="submit" value="POST"/> </form> <h3>put请求</h3> <form action="/rest/12" method="post"> <input type="hidden" name="_method" value="PUT" /> <input type="submit" value="PUT" /> </form> <h3>delete请求</h3> <input type="hidden" name="_method" value="DELETE"/> <form action="/rest/12" method="post"> <input type="hidden" name="_method" value="DELETE" /> <input type="submit" value="DELETE" /> </form> <h2>AJAX请求 测试</h2> <form action="" id="myForm" method="post"> id: <input type="text" id="id"> <br> name: <input type="text" id="name"> <br> age: <input type="text" id="age"> <br> <button type="button" id="getAjax">GET</button> <br> <button type="button" id="postAjax">POST</button> <br> <button type="button" id="putAjax">PUT</button> <br> <button type="button" id="deleteAjax">DELETE</button> <br> </form> <script> $(function(){ // get $("#getAjax").click(function(){ $.ajax({ type: "GET", url: "/rest/"+$("#id").val(), data:"name="+$("#name").val()+"&age="+$("#age").val(), dataType:"json", success: function(){} }); }); // post $("#postAjax").click(function(){ $.ajax({ type: "POST", url: "/rest/"+$("#id").val(), data:{ "name":$("#name").val(), "age":$("#age").val() }, dataType:"json", success: function(){} }); }); // put $("#putAjax").click(function(){ $.ajax({ type: "POST", url: "/rest/"+$("#id").val(), data:{ "_method":"PUT", "name":$("#name").val(), "age":$("#age").val() }, dataType:"json", success: function(){} }); }); //delect $("#deleteAjax").click(function(){ $.ajax({ type: "POST", url: "/rest/"+$("#id").val(), data:{ "_method":"DELETE", "name":$("#name").val(), "age":$("#age").val() }, dataType:"json", success: function(){} }); }); }); </script> </body> </html>
RestController
类 控制器
package com.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("rest") public class RestController { @RequestMapping("torest") public String torest() { return "jsp/rEST"; } @RequestMapping(value = "{id}",method = RequestMethod.GET) public String getTest(String name ,Integer age) { System.out.println("get请求"); System.out.println("name : " + name); System.out.println("age : " + age); return "jsp/ok"; } @RequestMapping(value = "{id}",method = RequestMethod.POST) public String postTest(String name ,Integer age) { System.out.println("post请求"); System.out.println("name : " + name); System.out.println("age : " + age); return "jsp/ok"; } @RequestMapping(value = "{id}",method = RequestMethod.PUT) public String putTest(String name ,Integer age) { System.out.println("put请求"); System.out.println("name : " + name); System.out.println("age : " + age); return "jsp/ok"; } @RequestMapping(value = "{id}",method = RequestMethod.DELETE) public String deleteTest(String name ,Integer age) { System.out.println("delete请求"); System.out.println("name : " + name); System.out.println("age : " + age); return "jsp/ok"; } }
通过进入页面进行点击测试响应!!!
如果资源有多级分类,不建议写多级URL如:
GET: /class/12/student/1002
建议=> GET:/class/12?student=1002
(查班级中指定学生)
采用Restful风格 PUT 和 DELETE 请求传递参数无效,传递到后台的参数值为 null
Tomcat封装请求说明:
- 将请求中的数据封装成map
- request.getParameter(Key)会获取map中的值
- SpringMVC封装了POJO对象,但POJO会通过 request.getParameter(Key) 进行获取,因此 UPT 和 DELETE 请求时 request.getParameter(Key) 会拿不到
- Tomcat检测到 PUT、DELETE不会封装请求 数据map
解决方案
利用POST请求 添加 _method
属性 值为 指定的 请求类型 (PUT、DELETE、…),前提需要过滤器
web.xml
配置过滤器 HiddenHttpMethodFilter
<!-- HiddenHttpMethodFilter过滤器可以将POST请求转化为put请求和delete请求! --> <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>
页面 请求
··· <!--form表单请求 添加隐藏 属性 _method 请求类型为 : PUT --> <form action="/rest/12" method="post"> <input type="hidden" name="_method" value="PUT" /> <input type="submit" value="PUT" /> </form> ··· <!--ajax请求 添加 属性 _method 请求类型为 :DELETE --> <button id="deleteAjax">DELETE请求</button> ··· <script> $(function(){ //delect $("#deleteAjax").click(function(){ $.ajax({ type: "POST", url: "/rest/12", data:{"_method":"DELETE"}, dataType:"json", success: function(){} }); }); }); </script>