HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE,它们分别对应四种基本的操作,
GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。
GET /order/1 HTTP/1.1:得到id=1的order
DELETE /order/1 HTTP/1.1:删除id=1的order
PUT /order/1 HTTP/1.1:更新id=1的order
POST /order HTTP/1.1:新增order
浏览器的form表单只支持GET和POST请求,而DELETE和PUT请求并不支持。为解决这个题,Spring3.0添加了一个 HiddenHttpMethodFilter 过滤器,可以将带有_method参数的http post请求转换为put或delete请求。从而解决问题。
需要在web.xml文件中配置一个HiddenHttpMethodFilter:
public class HiddenHttpMethodFilter extends OncePerRequestFilter { public static final String DEFAULT_METHOD_PARAM = "_method"; private String methodParam = DEFAULT_METHOD_PARAM; public void setMethodParam(String methodParam) { Assert.hasText(methodParam, "'methodParam' must not be empty"); this.methodParam = methodParam; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest requestToUse = request; if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) { String paramValue = request.getParameter(this.methodParam); if (StringUtils.hasLength(paramValue)) { requestToUse = new HttpMethodRequestWrapper(request, paramValue); } } filterChain.doFilter(requestToUse, response); } private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper { private final String method; public HttpMethodRequestWrapper(HttpServletRequest request, String method) { super(request); this.method = method.toUpperCase(Locale.ENGLISH); } @Override public String getMethod() { return this.method; } } }
我们可以看到:HttpMethodRequestWrapper即为请求与请求类型的封装。
<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>
在使用时,需要发送post请求时携带一个 name="_method" 的隐藏域,其值可以为GET/POST/DELETE/PUT。
<form action="test9" method="post">
<input type="hidden" name="_method" value="GET"/>
<input type="submit" value="GET"/>
</form>
<form action="test10" method="post">
<input type="hidden" name="_method" value="POST"/>
<input type="submit" value="POST"/>
</form>
<form action="test11" method="post">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="DELETE"/>
</form>
<form action="test12" method="post">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="PUT"/>
</form>
在RequestMapping注解中配置method属性值:
public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE }
@RequestMapping(value = "/test9", method = RequestMethod.GET)
@ResponseBody
public String test9() {
return "GET";
}
@RequestMapping(value = "/test10", method = RequestMethod.POST)
@ResponseBody
public String test10() {
return "POST";
}
@RequestMapping(value = "/test11", method = RequestMethod.DELETE)
@ResponseBody
public String test11() {
return "DELETE";
}
@RequestMapping(value = "/test12", method = RequestMethod.PUT)
@ResponseBody
public String test12() {
return "PUT";
}
当然_method属性也是可以自定义的:
<init-param> <param-name>methodParam</param-name> <param-value>_xiya</param-value> </init-param>