HiddenHttpMethodFilter
浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE、PUT 等 method 并不支持,spring3.0 添加了一个过滤器,可以将这
些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求,该过滤器为 HiddenHttpMethodFilter。
HiddenHttpMethodFilter 的父类是 OncePerRequestFilter,它继承了父类的 doFilterInternal()
方法,工作原理是将 jsp
页面的 form 表单的 method 属性值在 doFilterInternal()
方法中转化为标准的 Http 方法,即 GET、POST、 HEAD、
OPTIONS、PUT、DELETE、TRACE,然后到 Controller 中找到对应的方法。例如,在使用注解时我们可能会在 Controller 中用
于 @RequestMapping(value = “list”, method = RequestMethod.PUT),所以如果你的表单中使用的是
<form method="put">
,那么这个表单会被提交到标了 Method=“PUT” 的方法中。
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
private static final List<String> ALLOWED_METHODS;
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = "_method";
......
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
String paramValue = request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter((ServletRequest)requestToUse, response);
}
需要注意的是,由于 doFilterInternal()
方法只对 method 为 post 的表单进行过滤,所以在页面中必须如下设置:
<form action="..." method="post">
<input type="hidden" name="_method" value="put" />
......
</form>
同时,HiddenHttpMethodFilter 必须作用于 dispatcher 前。
同样的,作为 Filter,可以在 web.xml 中配置 HiddenHttpMethodFilter 的参数,可配置的参数为 methodParam,值必须为
GET,、POST、 HEAD、OPTIONS、PUT、DELETE、TRACE 中的一个。