使用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