/users/1)。HTML <form> 僅支持 method="GET|POST"。Spring 3.0 提供 HiddenHttpMethodFilter 破解:
_method=PUT(或 DELETE)。_method,包裝 HttpServletRequest 返回偽造的 method。@RequestMapping(method=RequestMethod.PUT) 匹配。<!-- 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>
<%@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>
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; }
}
若不想用 _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>
MultipartFilter → HiddenHttpMethodFilter → Spring Security Filter → OpenEntityManagerInViewFilter。/api/v1/users/1)。HiddenHttpMethodFilter 以極低成本讓傳統表單支持完整 REST 動詞,是 Spring MVC 向 REST 遷移的關鍵基礎設施。掌握 Filter 鏈順序與 methodParam 自定義,即可在任何項目中優雅實現 PUT/DELETE 表單提交。