在JQuery中,我們可以進行REST ful中delete和put的請求,但是在java EE標准中,默認只有在POST請求的時候,servlet 才會通過getparameter()方法取得請求體中的相應的請求參數的數據。而PUT,delete請求的請求體中數據則默認不會被解析。
- 關於delete請求:delete請求用來從服務器上刪除資源。因此我們只需要把要刪除的資源的ID上傳給服務器,即使是批量刪除的時候,也可以通過URL傳參的方式將多個id傳給servlet,因此,可以滿足我們的需求,可以直接發送請求。
- 關於put請求(指的是帶有請求體)
- 沒有文件時:SpringMVC提供了一個將post轉換為put和delete的方法,通過在web.xml中注冊一個HiddenHttpMethodFilter過濾器。
- 上傳文件時:我們可以通過在web.xml中注冊一個MultipartFilter,一定要在HiddenHttpMethodFilter之前。
SpringMVC實現PUT,DELETE請求
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>dispatcher</servlet-name>
</filter-mapping>
然后我們看源碼:
@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);
}
}
- this.methodParam屬性被默認初始化為"
_method
",通過request.getParameter(this.methodParam);
判斷是put還是delete, "POST".equals(request.getMethod())
,而且必須要求是post方式提交的,- 然后它把request進行包裝后傳給下一個filter。
- 因此,我們需要在提交的時候添加一個字段
<form action="" id="formData" name="formData" method="post">
<input type="text" name="username" id="username"/>
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="submit"/>
</form>
或者在$.ajax
中
function login() {
$.ajax({
type: "post",//請求方式
url: "", //發送請求地址
timeout: 30000,//超時時間:30秒
data: {
"username": $('#username').val(),
"password": $("#password").val(),
"_method": delete
},
dataType: "json",//設置返回數據的格式
success: function (data) {
console.log(data);
},
error: function () { //請求出錯的處理
}
});
}
然后我們就可以在后台@RequestMapping(value = "", method = RequestMethod.PUT)
注解中標識我們的方法,最后就可以成功地獲得數據。
SpringMVC實現PUT請求上傳文件
可是后來我又有遇到另外一個需求那就是修改的時候需要傳送文件到put方法中,於是這種方法就不可行了,但是我在HiddenHttpMethodFilter
源碼中看到這樣一句話
* <p><b>NOTE: This filter needs to run after multipart processing in case of a multipart
* POST request, due to its inherent need for checking a POST body parameter.</b>
* So typically, put a Spring {@link org.springframework.web.multipart.support.MultipartFilter}
* <i>before</i> this HiddenHttpMethodFilter in your {@code web.xml} filter chain.
和MultipartFilter源碼中這樣的注釋
/**
* Set the bean name of the MultipartResolver to fetch from Spring's
* root application context. Default is "filterMultipartResolver".
*/
- 也就是說我們可以通過在web.xml中注冊一個MultipartFilter,一定要在HiddenHttpMethodFilter之前。
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<servlet-name>dispatcher</servlet-name>
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
- 然后再在Spring的 root application context中添加如下代碼
<bean id="filterMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="209715200"/>
<property name="defaultEncoding" value="UTF-8"/>
<property name="resolveLazily" value="true"/>
</bean>
- FormData對象是html5的一個對象,目前的一些主流的瀏覽器都已經兼容。FormData對象是html5的一個對象,目前的一些主流的瀏覽器都已經兼容。
function test() {
var form = new FormData(document.getElementById("tf"));
form.append("_method", 'put');
$.ajax({
url: url,
type: 'post',
data: form,
processData: false,
contentType: false,
success: function (data) {
window.clearInterval(timer);
console.log("over..");
},
error: function (e) {
alert("錯誤!!");
window.clearInterval(timer);
}
});
get();//此處為上傳文件的進度條
}
<form id="tf" method="post" name="formDada" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="text" name="id"/>
<input type="text" name="name"/>
<input type="button" value="提" onclick="test()"/>
</form>
最后,就可以實現將文件上傳提交給put方法。