SpringMVC REST风格
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";
}
}
通过进入页面进行点击测试响应!!!
REST URL问题
避免多级URL
如果资源有多级分类,不建议写多级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>