爲了符合restful風格,最近在作項目時,除了GET和POST請求,還決定使用PUT和DELETE請求,可是在使用springMVC進行這個兩個類型的請求時web
$.ajax({ url:‘***’, type:‘put’, data:{} })
發現controller接收的自定義實體類形參的各個屬性都是null,緣由是瀏覽器自己只支持get和post方法,所以須要使用_method這個隱藏字段來告知spring這是一個put請求。因此type是不能變更的,不然瀏覽器不支持。 爲此,spring3.0添加了一個過濾器,能夠將這些請求轉換爲標準的http方法,使得支持GET、POST、PUT與DELETE請求,該過濾器是HiddenHttpMethodFilter。ajax
public class HiddenHttpMethodFilter extends OncePerRequestFilte{ /** Default method parameter: <code>_method</code> */ public static final String DEFAULT_METHOD_PARAM = "_method"; private String methodParam = DEFAULT_METHOD_PARAM; /** * Set the parameter name to look for HTTP methods. * @see #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 { 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的源碼你會發現這個過濾器的原理其實就是將http請求中的_method屬性值在doFilterInternal方法中轉化爲標準的http方法。
須要注意的是,doFilterInternal方法中的if條件判斷http請求是否POST類型而且請求參數中是否含有_method字段,也就是說方法只對method爲post的請求進行過濾,所喲請求必須以下設置:spring
$.ajax({ url:‘***’, type:‘post’, data:{ _method:put, } })
同時HiddenHttpMethodFilter必須做用於dispatch前,因此須要在web.xml中配置一個filter瀏覽器
<filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <servlet-name>ROOT</servlet-name> </filter-mapping>
這樣,springmvc就能處理put和delete請求了。
完。restful