首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring MVC REST 架構實戰:HiddenHttpMethodFilter 實現 PUT/DELETE 表單提交

     編輯:Java 相關知識

REST 核心概念

  • 資源:URI 唯一標識(如 /users/1)。
  • 表現層:JSON、XML、HTML 等展現形式。
  • 狀態轉移:通過 HTTP 動詞驅動資源狀態變化。
    • GET - 獲取
    • POST - 創建
    • PUT - 完整更新
    • DELETE - 刪除

瀏覽器表單限制

HTML <form> 僅支持 method="GET|POST"。Spring 3.0 提供 HiddenHttpMethodFilter 破解:

  1. 表單添加隱藏域 _method=PUT(或 DELETE)。
  2. Filter 攔截 POST 請求,讀取 _method,包裝 HttpServletRequest 返回偽造的 method。
  3. Controller 正常用 @RequestMapping(method=RequestMethod.PUT) 匹配。

完整配置步驟

1. web.xml 註冊 Filter(順序關鍵)

<!-- 1. MultipartFilter (若有文件上傳) -->
<filter>
    <filter-name>multipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    <init-param>
        <param-name>multipartResolverBeanName</param-name>
        <param-value>multipartResolver</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>multipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 2. HiddenHttpMethodFilter (在 Multipart 之後) -->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    <init-param>
        <param-name>methodParam</param-name>
        <param-value>_method</param-value> <!-- 默認即 _method,可自定義 -->
    </init-param>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. JSP 表單聲明

<%@taglib uri="https://www.springframework.org/tags/form" prefix="form" %>

<form:form modelAttribute="user" method="delete" action="${pageContext.request.contextPath}/user/1">
    <!-- 自動生成 <input type="hidden" name="_method" value="delete"/> -->
    <input type="submit" value="刪除用戶"/>
</form:form>

3. Controller 處理

Filter 源碼核心邏輯

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
    String paramValue = request.getParameter(this.methodParam); // 默認 _method
    if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
        String method = paramValue.toUpperCase(Locale.ENGLISH);
        HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
        chain.doFilter(wrapper, response);
    } else {
        chain.doFilter(request, response);
    }
}

// 內部包裝類
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
    private final String method;
    public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
        super(request); this.method = method;
    }
    @Override public String getMethod() { return this.method; }
}

自定義 methodParam 示例

若不想用 _method,可改為 _http_method:

<form:form method="post" methodParam="_http_method" ...>
    <input type="hidden" name="_http_method" value="put"/>
</form:form>

<init-param>
    <param-name>methodParam</param-name>
    <param-value>_http_method</param-value>
</init-param>

最佳實踐提醒

  • Filter 順序:MultipartFilter → HiddenHttpMethodFilter → Spring Security Filter → OpenEntityManagerInViewFilter。
  • 僅 POST 生效:GET 請求不會被轉換,避免幂等性破壞。
  • RESTful URL 設計:名詞複數、層級關係、版本號(/api/v1/users/1)。
  • 前後端分離項目:直接發送 PUT/DELETE(fetch/axios),無需此 Filter。

總結

HiddenHttpMethodFilter 以極低成本讓傳統表單支持完整 REST 動詞,是 Spring MVC 向 REST 遷移的關鍵基礎設施。掌握 Filter 鏈順序與 methodParam 自定義,即可在任何項目中優雅實現 PUT/DELETE 表單提交。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved