IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring Boot 文件上传与下载 -> 正文阅读

[Java知识库]Spring Boot 文件上传与下载

文件上传

上传到服务器的磁盘路径

@RestController
public class UpDownloadController{

    @RequestMapping("uploadFile")
    public String uploadFile(MultipartFile file) throws IOException {
        // 要保存到服务器的路径(根据实际需要修改)
        String remorePath = "/home/test";
        String fileName = file.getOriginalFilename();
        String filePath = remorePath+"/"+fileName;
        file.transferTo(new File(filePath));
        // 返回前端的文件访问地址(一般是http请求的地址,不要直接返回remorePath这样的磁盘路径)
        return remorePath; 
    }
}

文件上传,前端需设置请求头为:multipart/form-data。

MultipartFile常用方法说明

String getName():获取文件对应的表单参数名称

String getOriginalFilename():获取文件的名称

InputStream getInputStream():获取文件的输入流。我们的示例是上传到服务器的磁盘,很多项目可能是上传到文件服务器等。可通过该输入流将文件数据对接到文件服务器的对应接口上。

byte[] getBytes():获取文件的数据

void transferTo(File dest):将文件输出到定义的 dest 文件

带其他参数的文件上传

    @RequestMapping("uploadFile")
    public String uploadFile(Param param,MultipartFile file) throws IOException {
        log.error("文件上传参数:{}",param);
        // 要保存到服务器的路径(根据实际需要修改)
        String remorePath = "/home/test";
        String fileName = file.getOriginalFilename();
        String filePath = remorePath+"/"+fileName;
        file.transferTo(new File(filePath));
        // 返回前端的文件访问地址(一般是http请求的地址,不要直接返回remorePath这样的磁盘路径)
        return remorePath;
    }

其他参数的获取和普通的Controller获取一样。

文件下载

    @RequestMapping("downloadFile/{param1}/{param2}")
    public void downloadFile(@PathVariable Long param1, @PathVariable Long param2,String filePath, HttpServletResponse response) throws IOException {
        File f = new File("C:\\work\\test\\2022_11_01\\720513e0d488.txt");

        log.error("param1:{},param2:{},filePath:{}",param1,param2,filePath);
		// 下载为中文的文件名称
        String fileName = new String("测试下载".getBytes("UTF-8"),"ISO-8859-1") + ".txt";
        response.setContentType("application/force-download");// 设置强制下载不打开
        response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
        FileUtils.copyFile(f,response.getOutputStream());
        response.getOutputStream().close();
    }

注:fileName 如果直接使用汉字字符串,下载后文件名称变成了下划线。通过示例中的方式转换即可。

支持文件上传下载的配置说明

如果在 Spring MVC 下,需要配置 一个名称为 multipartResolver 的 MultipartResolver 类型的bean来支持文件上传。Spring-web包为其提供了两个实现CommonsMultipartResolver、StandardServletMultipartResolver

类名说明
CommonsMultipartResolver基于 Commons FileUpload 上仅适用于POST请求,但接受任何多部分/内容类型。
StandardServletMultipartResolver使用Servlet容器的多部分解析器,可能会使应用程序暴露于容器实现的差异。

如果要使用 CommonsMultipartResolver 需要引入 Commons FileUpload 依赖包。

spring boot 下,默认是可以不用什么配置,就支持文件的上传和下载的。我们来看看spring boot 的相关自动配置代码

@Bean(name = "multipartResolver")
	@ConditionalOnMissingBean(MultipartResolver.class)
	public StandardServletMultipartResolver multipartResolver() {
		StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
		multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
		return multipartResolver;
	}

说明Spring Boot 默认是使用的 StandardServletMultipartResolver。但其使用了条件注解,我们可以在我们的应用中使用 CommonsMultipartResolver 将其替换掉。

限制上传文件的大小

Spring Boot 自动配置中还有个类我们需要了解 MultipartProperties,文件上传的配置。其在application.properties 文件中的配置前缀为 spring.servlet.multipart

  • location:指定上载文件的存储目录。如果未指定,将使用临时目录。
  • max-file-size :指定上传文件允许的最大大小。默认值为1MB(意味着我们上传文件的默认最大大小为1MB)
  • max-request-size:指定多部分/表单数据请求允许的最大大小。默认值为10MB。
  • file-size-threshold :文件大小阈值指定文件将写入磁盘的大小阈值。默认值为0。
  • resolve-lazily:是否在文件或参数访问时延迟解析多部分请求

配置示例

# 上传文件的表单数据最大大小
spring.servlet.multipart.max-request-size= 20MB
# 上传文件的最大大小
spring.servlet.multipart.max-file-size= 5MB

常见问题解析

MaxUploadSizeExceededException 异常 @ControllerAdvice 标注的 ExceptionHandler 无法解析的问题

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (336958720) exceeds the configured maximum (20971520)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure(StandardMultipartHttpServletRequest.java:122)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:115)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.initializeMultipart(StandardMultipartHttpServletRequest.java:129)
	at org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest.getMultipartFiles(AbstractMultipartHttpServletRequest.java:141)
	at org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest.getFile(AbstractMultipartHttpServletRequest.java:88)
	at org.springframework.web.multipart.support.MultipartResolutionDelegate.resolveMultipartArgument(MultipartResolutionDelegate.java:108)
	at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:166)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:108)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:450)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at com.yyoo.mybase.base.filter.CorsFilter.doFilter(CorsFilter.java:58)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at com.yyoo.mybase.base.filter.xss.XssFilter.doFilter(XssFilter.java:75)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:142)
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (336958720) exceeds the configured maximum (20971520)
	at org.apache.catalina.connector.Request.parseParts(Request.java:2974)
	at org.apache.catalina.connector.Request.getParts(Request.java:2834)
	at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098)
	at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:361)
	at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:361)
	at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:361)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:95)
	... 81 common frames omitted
Caused by: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (336958720) exceeds the configured maximum (20971520)
	at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:161)
	at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.getMultiPartStream(FileItemIteratorImpl.java:205)
	at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:224)
	at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:142)
	at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:252)
	at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:276)
	at org.apache.catalina.connector.Request.parseParts(Request.java:2932)
	... 87 common frames omitted

由于我们Spring Boot 默认使用了容器的文件上传支持,所以此处的错误是 tomcat 容器报的,此处修改办法如下

修改配置文件

# 上传文件的表单数据最大大小
spring.servlet.multipart.max-request-size= 20MB
# 上传文件的最大大小
spring.servlet.multipart.max-file-size= 5MB
# 设置tomcat的允许大小为-1,不限制
server.tomcat.max-swallow-size = -1
# 是否在文件或参数访问时延迟解析多部分请求
spring.servlet.multipart.resolve-lazily=true

使用 CommonsMultipartResolver

  1. 添加依赖
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
  1. 配置 CommonsMultipartResolver
@Configuration
public class MyWebConfig {

    @Resource
    private MultipartProperties multipartProperties;

    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
    @ConditionalOnMissingBean(MultipartResolver.class)
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        // 完整请求的最大允许大小(参数单位是字节,-1标识不限制,默认-1)
        multipartResolver.setMaxUploadSize(multipartProperties.getMaxRequestSize().toBytes());
        // 单个上传文件的最大允许大小(参数单位是字节,-1标识不限制,默认-1)
        multipartResolver.setMaxUploadSizePerFile(multipartProperties.getMaxFileSize().toBytes());
        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
        return multipartResolver;
    }

}

重用了MultipartProperties 的几个配置。

注意:使用此方式也会有 MaxUploadSizeExceededException 无法通过ExceptionHandle 处理的问题。建议使用默认的 -1 不限制大小。然后在Controller 层添加过滤器或者直接在Controller中限制上传文件大小。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:12:25  更:2022-11-05 00:17:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 18:17:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码