SpringMVC控制器接收不了PUT提交的引數的解決方案
這次改造了下框架,把控制器的API全部REST化,不做不知道,SpringMVC的REST有各種坑讓你去跳,順利繞過它們花了我不少時間,這次來提下SpringMVC的PUT提交引數為null的情況。
照常先貼出我的控制器程式碼,沒什麼特別的,就是打印出接受到的前臺引數值:
@RequestMapping(value = "/{id}", method = RequestMethod.PUT) @ResponseBody public Map<String, Object> update( @RequestParam(value = "isform", required = false) String isform, @PathVariable("id") String id) { System.out.println("id value: " + id); System.out.println("isform value: " + isform); return null; }
很常規的PUT控制器,用來修改原有的記錄,原有的的web.xml中,我只添加了一個和REST涉及的過濾器
org.springframework.web.filter.HiddenHttpMethodFilter
<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>
這個因為大多數人都知道它的作用,這裡再囉嗦提一下:
瀏覽器form表單只支援GET與POST請求,而DELETE、PUT等method並不支援,spring3.0添加了一個過濾器,可以將這些請求轉 換為標準的http方法,使得支援GET、POST、PUT與DELETE請求,該過濾器為HiddenHttpMethodFilter,只需要在表單中新增一個隱藏欄位"_method"
<form action="..." method="post"> <input type="hidden" name="_method" value="put" /> ...... </form>
下邊我們來看下,執行的結果,我會在我的前臺發起一個PUT請求作為案例, 我們來看下後臺的引數列印情況:
id引數順利的獲取到了,因為它其實是由@PathVariable獲取的,這個沒有什麼問題,但是http body中提交的引數值isform卻為null,查詢了一番,原因是:
如果是使用的是PUT方式,SpringMVC預設將不會辨認到請求體中的引數,或者也有人說是Spirng MVC預設不支援 PUT請求帶引數,
解決方案也很簡單,就是在web.xml中把原來的過濾器改一下,換成org.springframework.web.filter.HttpPutFormContentFilter
<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在更改之後我們繼續一下剛才的案例,傳送一個PUT請求,引數基本都不變
看下後臺列印的結果: ok,現在已經可以成功的獲取並打印出前臺的引數。