REST
常規出牌的簡介
- REST:即 Representational State Transfer。(資源)表現層狀態轉化。是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便,所以正得到越來越多網站的採用
① 資源(Resources):網絡上的一個實體,或者說是網絡上的一個具體信息。
它可以是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的存在。
可以用一個URI(統一資源定位符)指向它,每種資源對應一個特定的 URI 。
獲取這個資源,訪問它的URI就可以,因此 URI 即爲每一個資源的獨一無二的識別符。
② 表現層(Representation):把資源具體呈現出來的形式,叫做它的表現層(Representation)。比如,文本可以用 txt 格式表現,也可以用 HTML 格式、XML 格式、JSON 格式表現,甚至可以採用二進制格式。
③ 狀態轉化(State Transfer):每發出一個請求,就代表了客戶端和服務器的一次交互過程。HTTP協議,是一個無狀態協議,即所有的狀態都保存在服務器端。因此,如果客戶端想要操作服務器,必須通過某種手段,讓服務器端發生“狀態轉化”(State Transfer)
而這種轉化是建立在表現層之上的,所以就是 “表現層狀態轉化”。
④具體說,就是 HTTP 協議裏面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。
它們分別對應四種基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。
背景
按照之前我們寫代碼的方式,對於需要增刪改查時,我們會向服務器發送不同的命令,比如
但是現在瀏覽器的請求方式只提供兩種,get和post請求,而沒有delete和put請求.springmvc就想到了這個方法,因爲web.xml的加載順序是監聽器先加載,然後到過濾器,最後纔是servlet被加載,所以springmvc就寫一個過濾器,get請求還是get,post請求會多帶一個參數_method,_method的值是put或者delete,當請求時post請求時,而且有_method參數的時候,就會根據_method參數的值轉化成對應參數的請求方式,這個過濾器就是HiddenHttpMethodFilter類,我們看下流程圖
結合原碼進行分析
因爲是springmvc提供好了,所以直接在web.xml配置就可以配置好就可以使用了
<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>
沒有例子是沒有靈魂的
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="testREST/110" method="get">
<input type="submit" value="GET">
</form>
<form action="testREST" method="post">
<input type="submit" value="POST">
</form>
<form action="testREST" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="PUT">
</form>
<form action="testREST/110" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="DELETD">
</form>
</body>
</html>
package test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class RESTController
{
@RequestMapping(value = "/testREST/{id}",method = RequestMethod.GET)
public String getUserById(@PathVariable("id")Integer id)
{
System.out.println("GET,id="+id);
return "success";
}
@RequestMapping(value = "/testREST",method = RequestMethod.POST)
public String insertUser()
{
System.out.println("POST");
return "success";
}
@RequestMapping(value = "/testREST",method = RequestMethod.PUT)
public String updateUser()
{
System.out.println("PUT");
return "success";
}
@RequestMapping(value = "/testREST/{id}",method = RequestMethod.DELETE)
public String deleteUser(@PathVariable("id")Integer id)
{
System.out.println("DELETE,id="+id);
return "success";
}
}
處理數據端的請求參數
package test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import bean.User;
@Controller
public class ParamController
{
/*
* springmvc獲取客戶端傳遞的參數的方式:
* 1.在處理請求的方法中,加入相應的形參,需要保證的是參數名和數據的參數名保持一致就可以自動賦值
* 不一致就需要@RequestParam來指定數據的參數名是什麼
* @RequestParam有三個屬性:
* value:設置數據參數名
* required:設置這個數據參數名是否必須,如果是必須又在數據裏面找不到就會報錯
* defaultValue:當獲取不到值的時候設置一個默認的值,一般用在分頁和模糊查詢中
*
* @RequestHeader:處理請求的方法上獲取請求頭信息,用法和@RequestParam一樣
* @CookieValue:獲取Cookie信息
*/
// @RequestMapping(value = "/param",method = RequestMethod.POST)
// public String param(@RequestParam(value="username",required = true,defaultValue = "jane1")String name,String password,String age)
// {
// System.out.println("username="+name+" password="+password+" age="+age);
// return "success";
// }
//
// @RequestMapping(value = "/param",method = RequestMethod.POST)
// public String param(@RequestHeader(value = "Accept-Language")String AcceptLanguage)
// {
// System.out.println("Accept-Language="+AcceptLanguage);
// return "success";
// }
//
// @RequestMapping(value = "/param",method = RequestMethod.POST)
// public String param(@CookieValue("JSESSIONID")String JSESSIONID)
// {
// System.out.println("JSESSIONID="+JSESSIONID);
// return "success";
// }
/*
* 使用POJO獲取客戶端數據,要求實體類對象中的屬性名和頁面中表單元素的name屬性值是一樣的
* 而且在表單中元素的名稱支持級聯關係
*
* 也可以通過設置形參的方式來獲取servletAPI
* 可以接受的servletAPI類型的參數有:
* HttpServletRequest,HttpServletResponseHttpSession,InputStream,OutputStream,Reader,Writer
*/
@RequestMapping(value = "/param",method = RequestMethod.POST)
public String param(User user , HttpServletRequest request,HttpServletResponse response)
{
System.out.println(request.getSession().getId());
System.out.println(user);
return "success";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="param" method="post">
username:<input name="username"/><br/>
password:<input name="password"/><br/>
age:<input name="age"/><br/>
province:<input name="address.province"/><br/>
city:<input name="address.city"/><br/>
country:<input name="address.country"/><br/>
<input type="submit"/>
</form>
</body>
</html>
package bean;
public class User
{
private Integer id;
private String username;
private String password;
private Address address;
//省略get和set方法
}
package bean;
public class Address
{
private String province;
private String city;
private String country;
//省略get和set方法
}