SpringMVC實現PUT請求上傳文件

在JQuery中,咱們能夠進行REST ful中delete和put的請求,可是在java EE標準中,默認只有在POST請求的時候,servlet 纔會經過getparameter()方法取得請求體中的相應的請求參數的數據。而PUT,delete請求的請求體中數據則默認不會被解析。javascript

  1. 關於delete請求:delete請求用來從服務器上刪除資源。所以咱們只須要把要刪除的資源的ID上傳給服務器,即便是批量刪除的時候,也能夠經過URL傳參的方式將多個id傳給servlet,所以,能夠知足咱們的需求,能夠直接發送請求。
  2. 關於put請求(指的是帶有請求體)
    1. 沒有文件時:SpringMVC提供了一個將post轉換爲put和delete的方法,經過在web.xml中註冊一個HiddenHttpMethodFilter過濾器。
    2. 上傳文件時:咱們能夠經過在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>

而後咱們看源碼:html

@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);
        }
    }
  1. this.methodParam屬性被默認初始化爲"_method",經過request.getParameter(this.methodParam);判斷是put仍是delete,
  2. "POST".equals(request.getMethod()),並且必需要求是post方式提交的,
  3. 而後它把request進行包裝後傳給下一個filter。
  4. 所以,咱們須要在提交的時候添加一個字段
<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>

或者在$.ajaxhtml5

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)註解中標識咱們的方法,最後就能夠成功地得到數據。java

SpringMVC實現PUT請求上傳文件

但是後來我又有遇到另一個需求那就是修改的時候須要傳送文件到put方法中,因而這種方法就不可行了,可是我在HiddenHttpMethodFilter源碼中看到這樣一句話web

* <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源碼中這樣的註釋ajax

/**
     * Set the bean name of the MultipartResolver to fetch from Spring's
     * root application context. Default is "filterMultipartResolver".
     */
  1. 也就是說咱們能夠經過在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>
  1. 而後再在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>
  1. 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方法。spring

相關文章
相關標籤/搜索