SpringBoot入门建站全系列(九)文件上传功能与下载方式

Spring对文件上传做了简单的封装,就是用MultipartFile这个对象去接收文件,当然有很多种写法,下面会一一介绍。

文件的下载很简单,给一个链接就行,而这个链接怎么生成,也有很多方式,下面也会讲解下常用的方式。

项目地址:
品茗IT-同步发布

品茗IT 提供在线支持:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

Mysql一键生成Mybatis注解Mapper

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

一、配置

本文假设你已经引入spring-boot-starter-web。已经是个SpringBoot项目了,如果不会搭建,可以打开这篇文章看一看《SpringBoot入门建站全系列(一)项目建立》。因为文件上传和下载不需要引入额外的jar包了。但是需要做如下配置:

application.properties 中需要添加下面的配置:

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=50MB

这里,

  • spring.servlet.multipart.max-file-size是对单个文件大小的限制。

  • spring.servlet.multipart.max-request-size是对单次请求的大小进行限制

至此,已经可以正常的进行上传下载了,就剩下写代码了。

二、文件上传的几种方式

2.1 单个文件上传

在Controller的RequestMapping注解的方法参数中,直接将MultipartFile作为参数传递进来。

package com.cff.springbootwork.web.file;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import com.cff.springbootwork.dto.ResultModel;
import com.cff.springbootwork.service.UploadService;@RestController
@RequestMapping("/file")
public class FileRest {private Logger log = LoggerFactory.getLogger(this.getClass());@Value("${upload.static.url}")private String uploadStaticUrl;@AutowiredUploadService uploadService;@RequestMapping("/upload")public ResultModel upload(@RequestParam("files") MultipartFile file) {try {if (file.isEmpty()) {return ResultModel.error("文件不能为空!");}String fileName = uploadService.saveUploadFile(file);return ResultModel.ok(uploadStaticUrl + fileName);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}
}

测试的时候,使用postman可以这样传参:

2.2 多个文件上传

在Controller的RequestMapping注解的方法参数中,直接将MultipartFile作为list传递进来。在FileRest中增加uploadList方法。

package com.cff.springbootwork.web.file;import java.util.ArrayList;
import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import com.cff.springbootwork.dto.ResultModel;
import com.cff.springbootwork.service.UploadService;@RestController
@RequestMapping("/file")
public class FileRest {private Logger log = LoggerFactory.getLogger(this.getClass());@Value("${upload.static.url}")private String uploadStaticUrl;@AutowiredUploadService uploadService;@RequestMapping("/upload")public ResultModel upload(@RequestParam("files") MultipartFile file) {try {if (file.isEmpty()) {return ResultModel.error("文件不能为空!");}String fileName = uploadService.saveUploadFile(file);return ResultModel.ok(uploadStaticUrl + fileName);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}@RequestMapping("/uploadList")public ResultModel uploadList(@RequestParam("files") List<MultipartFile> fileList) {try {List<String> list = new ArrayList<>();for (MultipartFile file : fileList) {String fileName = uploadService.saveUploadFile(file);list.add(uploadStaticUrl + fileName);}return ResultModel.ok(list);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}
}

测试的时候,使用postman可以这样传参:

2.3 从HttpServletRequest中取文件

新建uploadByRequest方法,将HttpServletRequest作为参数,Spring自动传入。

Spring对Request做了一层封装,如果有文件,它就是MultipartHttpServletRequest。
然后我们可以从MultipartHttpServletRequest获取到MultipartFile。后面的处理方式一样了。

package com.cff.springbootwork.web.file;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;import com.cff.springbootwork.dto.ResultModel;
import com.cff.springbootwork.service.UploadService;@RestController
@RequestMapping("/file")
public class FileRest {private Logger log = LoggerFactory.getLogger(this.getClass());@Value("${upload.static.url}")private String uploadStaticUrl;@AutowiredUploadService uploadService;@RequestMapping("/upload")public ResultModel upload(@RequestParam("files") MultipartFile file) {try {if (file.isEmpty()) {return ResultModel.error("文件不能为空!");}String fileName = uploadService.saveUploadFile(file);return ResultModel.ok(uploadStaticUrl + fileName);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}@RequestMapping("/uploadList")public ResultModel uploadList(@RequestParam("files") List<MultipartFile> fileList) {try {List<String> list = new ArrayList<>();for (MultipartFile file : fileList) {String fileName = uploadService.saveUploadFile(file);list.add(uploadStaticUrl + fileName);}return ResultModel.ok(list);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}@RequestMapping("/uploadByRequest")public ResultModel uploadByRequest(HttpServletRequest request) {try {Map<String, MultipartFile> files = new HashMap<>();if (request instanceof MultipartHttpServletRequest) {MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;MultiValueMap<String, MultipartFile> multiValueMap = req.getMultiFileMap();if (multiValueMap != null && !multiValueMap.isEmpty()) {for (String key : multiValueMap.keySet()) {files.put(key, multiValueMap.getFirst(key));}}}if (files.isEmpty())return ResultModel.error("文件木有?");List<String> list = new ArrayList<>();for (MultipartFile file : files.values()) {String fileName = uploadService.saveUploadFile(file);list.add(uploadStaticUrl + fileName);}return ResultModel.ok(list);} catch (Exception e) {e.printStackTrace();log.error("文件上传失败!", e);return ResultModel.error("文件上传失败!");}}
}

测试的时候,传参方式使用上面两种都可以了。

三、文件下载方式

文件上传成功后,我们同时会提供下载功能。下载功能很简单,有以下几种方式:

3.1 Spring配置映射

新建一个WebStaticConfig配置类,实现WebMvcConfigurer接口即可:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebStaticConfig implements WebMvcConfigurer {@Value("${upload.static.local}")private String uploadStaticLocal;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("file:" + uploadStaticLocal);}public String getUploadStaticLocal() {return uploadStaticLocal;}public void setUploadStaticLocal(String uploadStaticLocal) {this.uploadStaticLocal = uploadStaticLocal;}}

这句话将当前服务器(比如是http://127.0.0.1:8080)的/static路径(http://127.0.0.1:8080/static/)下的资源,映射到uploadStaticLocal指定的本地路径下的文件。

然后我们就可以直接访问文件了。

3.2 代理(nginx)映射

代理首选nginx了。高性能快捷的代理转发工具。

比如要将http://127.0.0.1:8081/static/下的资源,映射到/static/指定的本地路径下的文件,可以这样配置:

server {listen       8081;server_name  localhost;location /static {alias /static/;index index.html;}
}

这里为什么用8081而不是上面的8080了呢?因为上面的8080端口已经被SpringBoot应用占用了。nginx要在另一个端口监听了,如果非要将SpringBoot应用和静态资源在一个端口,可以对SpringBoot应用也做代理,例如:

server {listen       8081;server_name  localhost;location ^~ /api/ {proxy_pass   http://127.0.0.1:8080/;}location /static {alias /static/;index index.html;}
}

3.3 ResponseEntity读取文件并返回

比如我们在FileRest的Controller中建立个downloadFile方法,传入文件名,将文件读取为byte,包装成ResponseEntity返回。

 @RequestMapping(value = "/downloadFile", method = { RequestMethod.GET })public ResponseEntity<byte[]> downloadFile(@RequestParam("fileName") String fileName) {try {File file = new File(fileName);byte[] body = null;InputStream is = new FileInputStream(file);body = new byte[is.available()];is.read(body);is.close();HttpHeaders headers = new HttpHeaders();headers.add("Content-Disposition", "attchement;filename=" + file.getName());HttpStatus statusCode = HttpStatus.OK;ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);return entity;} catch (Exception e) {e.printStackTrace();return null;}}

四、过程中用到的实体及Service

详细完整的实体及Service,可以访问品茗IT-博客《SpringBoot入门建站全系列(九)文件上传功能与下载方式》

快速构建项目

Spring组件化构建

喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot技术吧!

SpringBoot入门建站全系列(九)文件上传功能与下载方式相关推荐

  1. SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室

    SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室 一.概述 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 ...

  2. SpringBoot入门建站全系列(二十六)Mongodb非关系型数据库的使用

    SpringBoot入门建站全系列(二十六)Mongodb非关系型数据库的使用 一.概述 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能 ...

  3. SpringBoot入门建站全系列(二十八)整合Kafka做日志监控

    SpringBoot入门建站全系列(二十八)整合Kafka做日志监控 一.概述 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端 ...

  4. SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用

    SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用 上一篇介绍了Mybatis的配置和基本用法<SpringBoot入门建站全系列(五)使用Spring-data-j ...

  5. springboot util 测试类怎么写_SpringBoot入门建站全系列(九)文件上传功能与下载方式...

    SpringBoot入门建站全系列(九)文件上传功能与下载方式 Spring对文件上传做了简单的封装,就是用MultipartFile这个对象去接收文件,当然有很多种写法,下面会一一介绍. 文件的下载 ...

  6. springboot mybatis ehcache_SpringBoot入门建站全系列(十四)集成Redis缓存

    SpringBoot入门建站全系列(十四)集成Redis缓存 一.概述 本地缓存,就是使用应用内使用本地内存将数据暂缓存储,一般数据库的查询如果不怎么改动,可以用本地缓存暂存. 远程缓存,比如redi ...

  7. spring配置文件_SpringBoot入门建站全系列(二十三)配置文件优先级及自定义配置文件...

    SpringBoot入门建站全系列(二十三)配置文件优先级及自定义配置文件 一.概述 Spring Boot允许多种配置来源,官网是这样说的: Spring Boot使用一种非常特殊的Property ...

  8. python建站部署_SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台...

    SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台 一.概述 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源 ...

  9. spring boot 入门_SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作

    SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作 一.概述 多数据源,就是有多个数据库的配置. 多数据源配置并不麻烦,使用起来和单数据源基本相同,但是,重要的是事务的控制 ...

最新文章

  1. MySQL 高级 - 存储过程 - 语法 - repeat循环
  2. 出现opencv error: assertion failed..........错误时, 一步解决
  3. [architecture]-ARMV8的一些总结-一篇就够了
  4. 使用机器学习预测天气_如何使用机器学习预测着陆
  5. Oracle 远程 RAC 打造双活数据中心 | 从容灾迈向双活案例分享
  6. jQuery设置文本框回车事件
  7. 卸载IE11并恢复到IE9
  8. 编译原理(龙书):第七章部分题目参考答案
  9. 论文写作过程中用到的软件、网站分享
  10. PHP反三角函数,反三角函数求导公式
  11. 微信网页开发(3)--微信网页授权
  12. 匿名访问ftp服务器
  13. 如何用PS把照片变成红/白/蓝底
  14. 2021年芯片产业发展的五大关键词
  15. random.seed()的用法
  16. 基于DRV8701芯片的全桥驱动电路
  17. 问题排除:电机摩擦力怎么计算?
  18. 想不想恶搞你的朋友?试试关不掉的弹窗(vbs)
  19. BZOJ 1455: 罗马游戏( 配对堆 + 并查集 )
  20. 单片机实验----跑马灯

热门文章

  1. 在桌面建立 LNK 快捷方式
  2. [微力同步 v2.4.2] 跨平台文件同步工具+使用P2P协议同步分发和合并文件+WAN同步加速
  3. iOS 动画原理与实现--帧动画、逐帧动画、CALayer
  4. IDC 发布《2020 年第四季度中国软件定义存储及超融合市场报告》,SmartX 超融合软件金融行业排名第一
  5. Codeforces 314B
  6. BZOJ2456 mode
  7. 我的计算机中的“ Web文件夹”图标是什么以及如何删除它?
  8. RAW图像编辑软件Capture One pro 21完美兼容m1
  9. [转载]我的C++技巧总结
  10. ocz固态硬盘开卡工具_将我的Lenovo W500升级到OCZ Vertex 250GB SATA II固态磁盘(SSD)...