SpringMVC(2)-Rest請求風格

marigo發表於2024-05-02

REST:Representational State Transfer,(資源)表現層狀態轉化。REST是目前流行的請求方式。
在HTTP協議中,有四個基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。REST就是透過get/post/put/delete說明crud的型別。

REST的核心過濾器

瀏覽器form表單只支援GET和POST請求,Spring增添了一個過濾器HiddenHttpMethodFilter,可以將這些請求轉換成標準的http方法,從而可以支援get/post/put/delete請求。具體點說,HiddenHttpMethodFilter只能對Post方法轉換成PUT和DELETE方法。

案例

需求:按照REST風格完成增刪改查

  1. 配置HiddenHttpMethodFilter,位置在web.xml
    1. <url-pattern>/*</url-pattern> 表示只要是有請求,我們都要透過這個過濾器
<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>
  1. 配置springDispatcherServlet-servlet.xml
    1. mvc:annotation-driven 表示支援 SpringMVC的高階功能,比如JSR303校驗、對映動態請求
    2. mvc:default-servlet-handler 表示將SpringMVC不能處理的請求交給Tomcat,比如請求css、js
<mvc:annotation-driven></mvc:annotation-driven>  
<mvc:default-servlet-handler/>

GET

  1. 前端
<a href="user/book/100">點選查詢書籍</a>
  1. 後端
@GetMapping(value = "/book/{id}")  
public String getBook(@PathVariable("id") String id) {  
    System.out.println("查詢書籍 id=" + id );  
    return "success";  
}

POST

  1. 前端
<form action="user/book" method="post">  
    name:<input name="bookName" type="text"><br>  
    <input type="submit" value="新增書籍">  
</form>
  1. 後端
@PostMapping(value = "/book")  
public String addBook(String bookName) {  
    System.out.println("新增書籍 bookName== " + bookName);  
    return "success";  
}

PUT

  1. 前端
<form action="user/book/100" method="post">  
    <input type="hidden" name="_method" value="PUT">  
    <input type="submit" value="修改書籍~">  
</form>
  1. 後端
@PutMapping(value = "/book/{id}")  
public String updateBook(@PathVariable("id") String id) {  
    System.out.println("修改書籍 id=" + id);  
    return "redirect:/user/success";  
}  
@RequestMapping(value = "/success")  
public String successGenecal() {  
    return "success"; //由該方法 轉發到 success.jsp 頁面  
}

DELETE

  1. 前端
<a href="user/book/100" id="deleteBook">刪除指定 id 的書</a>

預設情況下,<a href="user/book/100" id="deleteBook">刪除指定 id 的書</a>是get請求。
怎麼將get請求自動轉換成SpringMVC可以識別的delete請求?HiddenHttpMethodFilter機制。
可是隻有POST請求才能透過HiddenHttpMethodFilter機制轉換成DELETE和PUT請求,需要用到jquery在前端進行處理:

<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">  
    $(function () { // 頁面載入後就執行  
        // 1. 給刪除按鈕新增點選事件  
        $("#deleteBook").click(function () {  
            alert("ok");  
            var href = this.href;  
            $("#hiddenForm").attr("action", href); // 超連結的地址給表單  
            $(":hidden").val("DELETE"); // 設定隱藏域的值  
            $("#hiddenForm").submit();//這裡就是提交刪除請求了  
            //這裡必須返回 false,否則會提交兩次  
            return false;  
        });  
    })  
</script>
<a href="user/book/100" id="deleteBook">刪除指定 id 的書</a>
<form action="" method="POST" id="hiddenForm">  
    <input type="hidden" name="_method"/>  
</form>

相當於點選刪除連結(get)請求,轉成透過表單(post請求)傳送出去
2. 後端

@DeleteMapping(value = "/book/{id}")  
public String delBook(@PathVariable("id") String id) {  
    System.out.println("刪除書籍 id= " + id);  
    //return "success"; [如果這樣返回會報錯 JSPs only permit GET POST or HEAD]    
    return "redirect:/user/success"; //重定向到一個沒有指定 method 的 Handler 方法  
}

@RequestMapping(value = "/success")  
public String successGenecal() {  
    return "success"; //由該方法 轉發到 success.jsp 頁面  
}

補充

  1. 什麼是JSR303校驗
    JSR 303,被稱為Bean Validation API,是一種用於Java環境的標準資料驗證技術。比如註冊一個新賬號,系統需要確保你輸入的資料是有效的,比如電子郵件地址格式正確,密碼強度足夠,年齡在允許的範圍內等。JSR 303正是為了解決這種需求而設計的。
    這個標準允許開發者透過一套簡單的註解,來宣告驗證規則,這些規則直接加在Java類的欄位上。比如,我們可以用@NotNull註解來表示一個欄位不可以為空,用@Size(min=2, max=30)來限定字串的長度必須在2到30個字元之間。這樣,當資料透過這些帶有驗證規則的欄位時,系統會自動檢查這些條件是否滿足,如果不滿足,就會丟擲一個異常或返回錯誤資訊。
    透過JSR 303,開發者可以在程式碼層面保證資料的正確性和合理性,減少了程式執行時的錯誤和資料處理的複雜性。這就像是給資料裝上了一個自動檢查的過濾網,確保所有透過的資料都是乾淨、有效、符合規定的,從而讓整個軟體系統更加穩定可靠。

相關文章