实现HTTP PUT方式上传文件。

[亡魂溺海] 提交于 2019-12-20 12:06:09

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

使用restful方式编程,有时候put方式修改文件。但是默认情况下很多浏览器(比如:chrom)不支持put方式修改文件。spring默认情况下也不支持PUT方式修改文件。如果想要支持,方式如下:

一、后端覆盖StandardServletMultipartResolver。

通过查看springboot的文档,默认情况下,spring使用在配置文件中MultipartAutoConfiguration 中配置了上传文件的默认类StandardServletMultipartResolver 如下:

StandardServletMultipartResolver 里面有下面的内容:表示POST方式才用上传文件的方式处理。

所以我们就要把这个默认的去掉。也就是写一个类继承StandardServletMultipartResolver ,并重写它的isMultipart方法。

 

二、网上错误的做法:

网上找资料都说要继承CommonsMultipartResolver ,并重写isMultipart方法,这种方式是错误的,会使得spring对文件类型的参数绑定失效。例如:@RequestParam("files") List<MultipartFile> files 获取不到文件内容。

这种做法 如下:

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

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

注意上面上传文件的时候,用到一个commons-fileupload包,所以得导入这个包。


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

 

四、正确的做法:

就是把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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!