使用restful方式編程,有時候put方式修改文件。可是默認狀況下不少瀏覽器(好比:chrom)不支持put方式修改文件。spring默認狀況下也不支持PUT方式修改文件。若是想要支持,方式以下:html
經過查看springboot的文檔,默認狀況下,spring使用在配置文件中MultipartAutoConfiguration
中配置了上傳文件的默認類StandardServletMultipartResolver 以下:前端
StandardServletMultipartResolver 裏面有下面的內容:表示POST方式才用上傳文件的方式處理。java
因此咱們就要把這個默認的去掉。也就是寫一個類繼承StandardServletMultipartResolver ,並重寫它的isMultipart方法。git
網上找資料都說要繼承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>
前端調用的時候,因爲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/7981640/spring-3-0-fileupload-only-with-post/33658066#33658066 (裏面有測試方法編寫)
https://stackoverflow.com/questions/18728100/file-upload-via-http-put-request