1. 程式人生 > >【SpringMVC】3.REST表現層狀態轉換

【SpringMVC】3.REST表現層狀態轉換

注意!!! 此文章需要配置了SpringDispatcherServlet和InternalResourceViewResolver才能夠使用,如果不會配置,請翻看我【SpringMVC】系列的第一篇文章《【SpringMVC】1. SpringMVC的第一個程式——HelloWorld》 ##一、什麼是REST

表現層狀態轉換(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士於2000年在他的博士論文[1] 中提出來的一種全球資訊網軟體架構風格,目的是便於不同軟體/程式在網路(例如網際網路)中互相傳遞資訊。表現層狀態轉換(REST,英文:Representational State Transfer)是根基於超文字傳輸協議(HTTP)之上而確定的一組約束和屬性,是一種設計提供全球資訊網絡服務的軟體構建風格。匹配或兼容於這種架構風格(簡稱為 REST 或 RESTful)的網路服務,允許客戶端發出以統一資源識別符號訪問和操作網路資源的請求,而與預先定義好的無狀態操作集一致化。因此表現層狀態轉換提供了在網際網路絡的計算系統之間,彼此資源可互動使用的協作性質(interoperability)。相對於其它種類的網路服務,例如 SOAP服務則是以本身所定義的操作集,來訪問網路上的資源。 —維基百科

《表現層狀態轉換》

###要點及標準 要注意的是,REST是設計風格而不是標準。REST通常基於使用HTTP,URI,和XML以及HTML這些現有的廣泛流行的協議和標準。

  • 資源是由URI來指定。
  • 對資源的操作包括獲取、建立、修改和刪除資源,這些操作正好對應HTTP協議提供的GET、POST、PUT和DELETE方法。
  • 通過操作資源的表現形式來操作資源。
  • 資源的表現形式則是XML或者HTML,取決於讀者是機器還是人,是消費web服務的客戶軟體還是web瀏覽器。當然也可以是任何其他的格式。 這裡寫圖片描述

**更多內容請點選:**維基百科《表現層狀態轉換》進行了解 ##二、@PathVariable

在瞭解了什麼是REST風格的地址後,我們可以瞭解下@PathVariable

註解,這個註解是專門用來獲取REST風格地址引數。

  • 帶佔位符的URL是Spring3.0 新增的功能,該功能在SpringMVC向REST 目標挺進發展過程中具有里程碑的意義
  • 通過 @PathVariable 可以將URL中佔位符引數繫結到控制器處理方法的入參中:URL 中的 {xxx} 佔位符可以通過@PathVariable("xxx")繫結到操作方法的入參中。 ###(1)在com.springmvc.handlers中建立一個Handle類SpringMVCTest
package com.springmvc.handlers;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

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.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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 org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.springmvc.entities.User;

@SessionAttributes(value = { "user" }, types = { String.class })
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

	private static final String SUCCESS = "success";
	
	/**
	 * @PathVariable 可以用來對映URL中的佔位符到目標方法的引數
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/testPathVariable/{id}")
	public String testPathVariable(@PathVariable("id") Integer id) {
		System.out.println("testPathVariable id:" + id);
		return SUCCESS;
	}
}
	

###(2)在WebRoot資料夾根目錄建立`index.jsp`
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'index.jsp' starting page</title>
</head>

<body>
<a href="springmvc/testPathVariable/1">testPathVariable</a>
</body>

</html>
###(3)在WEB-INF資料夾下建立views,並在views下建立`success.jsp`檔案
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>success</title>
</head>

<body>
	<h1>Success page</h1>
</body>
</html>

###(4)執行Tomcat,訪問index.jsp ![這裡寫圖片描述](https://img-blog.csdn.net/201808211124162?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNTk2OTc4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 直接點選超連結`testPathVariable `即可,上面那些是我上一篇教程留下來的東西,不用去管。 點選超連結後跳轉到Success頁面,然後檢視MyEclipse的控制檯

這裡寫圖片描述 發現id已經從連結http://localhost:8080/springmvc-1/springmvc/testPathVariable/1獲取出來。 ##三、使用GET、POST、PUT 與DELETE 請求

HTTP 協議裡面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:

  1. GET 用來獲取資源
  2. POST 用來新建資源
  3. PUT 用來更新資源
  4. DELETE 用來刪除資源。

如何傳送PUT請求和DELETE請求? 1.需要配置HiddenHttpMethodFilter 2.請求頁面需要傳送POST請求 3.需要在傳送POST請求時攜帶一個name="_method"的隱藏域,值為DELETE,或PUT

###(1)在web.xml中配置HiddenHttpMethodFilter 使用HiddenHttpMethodFilter指定HTTP的請求型別:瀏覽器 form 表單只支援GET與POST請求,而DELETE、PUT 等 method 並不支援,Spring3.0 添加了一個過濾器,可以將這些請求轉換為標準的 http 方法,使得支援 GET、POST、PUT 與DELETE 請求。

<!-- 配置org.springframework.web.filter.HiddenHttpMethodFilter 可以把POST請求轉換為DELETE或者POST請求 -->
	<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>
###(2)在`com.springmvc.handlers`中建立Handler類`SpringMVC` 並且寫入相關的請求方法
package com.springmvc.handlers;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

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.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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 org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.springmvc.entities.User;

@SessionAttributes(value = { "user" }, types = { String.class })
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
	/*
	 * REST風格的URL 以CRUD為例: 
	 * 新增:/order POST 
	 * 修改:/order/1 PUT 
	 * update?id=1
	 * 獲取:/order/1 GET get?id=1 
	 * 刪除:/order/1 DELETE delete?id=1
	 * 
	 * 如何傳送PUT請求和DELETE請求? 
	 * 1.需要配置HiddenHttpMethodFilter 
	 * 2.需要傳送POST請求
	 * 3.需要在傳送POST請求時攜帶一個name="_method"的隱藏域,值為DELETE,或PUT
	 * 
	 * 在SpringMVC的目標方法中如何獲得id? 使用@PathVariable註解
	 */
	@RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
	public String testRest(@PathVariable("id") Integer id) {
		System.out.println("testRest id:" + id);
		return SUCCESS;
	}

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

	@RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
	@ResponseBody
	public String testRestDelete(@PathVariable("id") Integer id) {
		System.out.println("testRest Delete:" + id);
		return SUCCESS;
	}

	@RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
	@ResponseBody
	public String testRestPut(@PathVariable("id") Integer id) {
		System.out.println("testRest put:" + id);
		return SUCCESS;
	}
}
###(3)在`WebRoot`的根目錄下建立`index.jsp`
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'index.jsp' starting page</title>
</head>

<body>
<a href="springmvc/testRest/1">TestRest Get</a>
	<br>
	<br>
	<form action="springmvc/testRest" method="post">
		<input type="submit" value="TestRest POST"/>
	</form>
	<br>
	<br>
	<form action="springmvc/testRest/1" method="post">
		<input type="hidden" name="_method" value="DELETE"/> 
		<input type="submit" value="TestRest DELETE"/>
	</form>
	<br>
	<br>
	<form action="springmvc/testRest/1" method="post">
		<input type="hidden" name="_method" value="PUT"/> 
		<input type="submit" value="TestRest PUT"/>
	</form>
	</body>

</html>
###(4)效果展示 啟動TomCat伺服器後,訪問index主頁:http://localhost:8080/springmvc-1/index.jsp ![這裡寫圖片描述](https://img-blog.csdn.net/20180821213845570?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNTk2OTc4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
由於我的index頁面包含前幾篇文章的程式碼,所以多出了幾個超連結,只需關注紅框位置就好

1.測試超連結TestRestGet

這裡寫圖片描述

超連結TestRestGet能夠正常訪問
2.測試表單提交按鈕TestRestPOST 這裡寫圖片描述
按鈕TestRestPOST能夠正常訪問
這裡寫圖片描述 3.測試表單提交按鈕TestRestDELETE 這裡寫圖片描述 這裡寫圖片描述
按鈕TestRestDELETE能夠正常訪問
4.測試表單提交按鈕TestRestPUT 這裡寫圖片描述 這裡寫圖片描述
按鈕TestRestPUT能夠正常訪問