因为我身边很少有人用到GET和POST以外的method,说这些可能没什么意义。
而且不支持部分method的浏览器也只是一部分,不喜欢讨论浏览器兼容性什么的...
但兴许可以从Spring提供的方式里想到别的什么呢。
在此记录处理HTTP method的两个特性。
・Spring form标签
・org.springframework.web.filter.HiddenHttpMethodFilter
其实处理的思路很简单,比如我在页面中写一个
<input type="hidden" name="realMethod" value="delete" />
然后我写个filter去获取"真正"的HTTP method。
也许每一次都在一个form下写一个hidden感觉有些多余,于是我可能需要做一个form taglib。
的确,这样高雅了不少,但又多了一份差事。
于是我们可以使用Spring form标签。
引入taglib:
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
然后和html标签没什么区别了,只不过表单的method是delete:
<sf:form method="delete" action="userList"> </sf:form>
在controller里写一个方法,在@RequestMapping中设置接收的method为delete:
@RequestMapping(value ="/userList",method=RequestMethod.DELETE,headers={"Accept="+MediaType.APPLICATION_JSON_VALUE}) public @ResponseBody User[] queryUserList(){ System.out.println("delete+++"); User[] u = new User[4]; u[0] = new User("0001","King","t;stmdtkg"); u[1] = new User("0001","King","t;stmdtkg"); u[2] = new User("0001","King","t;stmdtkg"); u[3] = new User("0001","King","t;stmdtkg"); return u; }
此时访问的话仍然是405,关键还是HiddenHttpMethodFilter。
将HiddenHttpMethodFilter配置与web.xml中:
<filter> <filter-name>httpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>httpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
HiddenHttpMethodFilter重写OncePerRequestFilter的doFilterInternal,代码非常简单:
public static final String DEFAULT_METHOD_PARAM = "_method"; private String methodParam = DEFAULT_METHOD_PARAM; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String paramValue = request.getParameter(this.methodParam); if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method); filterChain.doFilter(wrapper, response); } else { filterChain.doFilter(request, response); } }
经过这个Filter,到达dispatcherServlet时method就是delete了。