實現HTTP PUT方式上傳文件。

使用restful方式編程,有時候put方式修改文件。可是默認狀況下不少瀏覽器(好比:chrom)不支持put方式修改文件。spring默認狀況下也不支持PUT方式修改文件。若是想要支持,方式以下:html

1、後端覆蓋StandardServletMultipartResolver。

經過查看springboot的文檔,默認狀況下,spring使用在配置文件中MultipartAutoConfiguration 中配置了上傳文件的默認類StandardServletMultipartResolver 以下:前端

StandardServletMultipartResolver 裏面有下面的內容:表示POST方式才用上傳文件的方式處理。java

因此咱們就要把這個默認的去掉。也就是寫一個類繼承StandardServletMultipartResolver ,並重寫它的isMultipart方法。git

 

2、網上錯誤的作法:

網上找資料都說要繼承CommonsMultipartResolver ,並重寫isMultipart方法,這種方式是錯誤的,會使得spring對文件類型的參數綁定失效。例如:@RequestParam("files") List<MultipartFile> files 獲取不到文件內容。github

這種作法 以下:web

import org.apache.commons.fileupload.FileUploadBase;
import org.springframework.http.HttpMethod;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

public class PostAndPutCommonsMultipartResolver extends CommonsMultipartResolver {

    private static final String POST_METHOD = "POST";
    private static final String PUT_METHOD = "PUT";

    @Override
    public boolean isMultipart(HttpServletRequest request) {

        boolean isMultipartRequest = false;

        if (request != null) {
            HttpMethod httpMethod = HttpMethod.valueOf(request.getMethod());

            if (Objects.equals(HttpMethod.POST,httpMethod) || Objects.equals(HttpMethod.PUT,httpMethod)) {
//                isMultipartRequest = FileUploadBase.isMultipartContent(new ServletRequestContext(request));
                isMultipartRequest = FileUploadBase.isMultipartContent(new ServletRequestContext(request));
            }
        }
        return isMultipartRequest;
    }
}

而後,配置bean覆蓋默認的CommonsMultipartResolver spring

@Bean(name = "multipartResolver")
    public CommonsMultipartResolver createMultipartResolver() {
        return new PostAndPutCommonsMultipartResolver();
    }

注意上面上傳文件的時候,用到一個commons-fileupload包,因此得導入這個包。apache

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

 

3、前端調用:

前端調用的時候,因爲chrom不支持PUT請求。若是寫method="PUT"會自動轉爲GET方式。編程

因此在form表單上須要method="POST" 。以POST方式提交。可是在參數裏面加上<input type="hidden" name="_method" value="PUT" />,spring接收到這個參數後,後臺會以PUT的方式路由到對應的PUT方法上。後端

<form action="/customers/dV" method="POST"  enctype="multipart/form-data">

	<input type="hidden" name="_method" value="PUT" />
	<input type="text" name="id" value="dV"/>
	<input type="file" name="coverImg"/>
	<input type="submit" value="提交"/>

</form>

 

4、正確的作法:

就是把PostAndPutCommonsMultipartResolver繼承StandardServletMultipartResolver 。重寫isMultipart方法。

public class PostAndPutCommonsMultipartResolver extends StandardServletMultipartResolver {

    private static final String POST_METHOD = "POST";
    private static final String PUT_METHOD = "PUT";

    @Override
    public boolean isMultipart(HttpServletRequest request) {

        boolean isMultipartRequest = false;

        if (request != null) {
            HttpMethod httpMethod = HttpMethod.valueOf(request.getMethod());

            if (Objects.equals(HttpMethod.POST,httpMethod) || Objects.equals(HttpMethod.PUT,httpMethod)) {
                String contentType = request.getContentType();

                isMultipartRequest = (contentType != null && contentType.toLowerCase().startsWith("multipart/"));
            }
        }
        return isMultipartRequest;
    }
}

 

不要忘記配置bean:參考MultipartAutoConfiguration 的配置。

@Autowired
    private  MultipartProperties multipartProperties;
    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
    public StandardServletMultipartResolver multipartResolver() {
        PostAndPutCommonsMultipartResolver multipartResolver = new PostAndPutCommonsMultipartResolver();
        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
        return multipartResolver;
    }

前端調用和上面同樣。

參考文檔:

https://stackoverflow.com/questions/12616928/restful-put-with-file-upload-and-form-data-in-spring-mvc

https://stackoverflow.com/questions/7981640/spring-3-0-fileupload-only-with-post/33658066#33658066 (裏面有測試方法編寫)

https://stackoverflow.com/questions/18728100/file-upload-via-http-put-request

相關文章
相關標籤/搜索