SpringBoot入门建站全系列(九)文件上传功能与下载方式
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入门建站全系列(九)文件上传功能与下载方式相关推荐
- SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室
SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室 一.概述 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 ...
- SpringBoot入门建站全系列(二十六)Mongodb非关系型数据库的使用
SpringBoot入门建站全系列(二十六)Mongodb非关系型数据库的使用 一.概述 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能 ...
- SpringBoot入门建站全系列(二十八)整合Kafka做日志监控
SpringBoot入门建站全系列(二十八)整合Kafka做日志监控 一.概述 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端 ...
- SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用
SpringBoot入门建站全系列(六)Spring-data-jpa进阶使用 上一篇介绍了Mybatis的配置和基本用法<SpringBoot入门建站全系列(五)使用Spring-data-j ...
- springboot util 测试类怎么写_SpringBoot入门建站全系列(九)文件上传功能与下载方式...
SpringBoot入门建站全系列(九)文件上传功能与下载方式 Spring对文件上传做了简单的封装,就是用MultipartFile这个对象去接收文件,当然有很多种写法,下面会一一介绍. 文件的下载 ...
- springboot mybatis ehcache_SpringBoot入门建站全系列(十四)集成Redis缓存
SpringBoot入门建站全系列(十四)集成Redis缓存 一.概述 本地缓存,就是使用应用内使用本地内存将数据暂缓存储,一般数据库的查询如果不怎么改动,可以用本地缓存暂存. 远程缓存,比如redi ...
- spring配置文件_SpringBoot入门建站全系列(二十三)配置文件优先级及自定义配置文件...
SpringBoot入门建站全系列(二十三)配置文件优先级及自定义配置文件 一.概述 Spring Boot允许多种配置来源,官网是这样说的: Spring Boot使用一种非常特殊的Property ...
- python建站部署_SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台...
SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台 一.概述 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源 ...
- spring boot 入门_SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作
SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作 一.概述 多数据源,就是有多个数据库的配置. 多数据源配置并不麻烦,使用起来和单数据源基本相同,但是,重要的是事务的控制 ...
最新文章
- MySQL 高级 - 存储过程 - 语法 - repeat循环
- 出现opencv error: assertion failed..........错误时, 一步解决
- [architecture]-ARMV8的一些总结-一篇就够了
- 使用机器学习预测天气_如何使用机器学习预测着陆
- Oracle 远程 RAC 打造双活数据中心 | 从容灾迈向双活案例分享
- jQuery设置文本框回车事件
- 卸载IE11并恢复到IE9
- 编译原理(龙书):第七章部分题目参考答案
- 论文写作过程中用到的软件、网站分享
- PHP反三角函数,反三角函数求导公式
- 微信网页开发(3)--微信网页授权
- 匿名访问ftp服务器
- 如何用PS把照片变成红/白/蓝底
- 2021年芯片产业发展的五大关键词
- random.seed()的用法
- 基于DRV8701芯片的全桥驱动电路
- 问题排除:电机摩擦力怎么计算?
- 想不想恶搞你的朋友?试试关不掉的弹窗(vbs)
- BZOJ 1455: 罗马游戏( 配对堆 + 并查集 )
- 单片机实验----跑马灯
热门文章
- 在桌面建立 LNK 快捷方式
- [微力同步 v2.4.2] 跨平台文件同步工具+使用P2P协议同步分发和合并文件+WAN同步加速
- iOS 动画原理与实现--帧动画、逐帧动画、CALayer
- IDC 发布《2020 年第四季度中国软件定义存储及超融合市场报告》,SmartX 超融合软件金融行业排名第一
- Codeforces 314B
- BZOJ2456 mode
- 我的计算机中的“ Web文件夹”图标是什么以及如何删除它?
- RAW图像编辑软件Capture One pro 21完美兼容m1
- [转载]我的C++技巧总结
- ocz固态硬盘开卡工具_将我的Lenovo W500升级到OCZ Vertex 250GB SATA II固态磁盘(SSD)...