banner
NEWS LETTER

Scroll down

title: 06-spring-boot-文件上传下载
categories: springboot

环境准备

1 导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>

2 配置文件上传下载配置

1
2
3
4
5
6
7
8
9
10
11
12
13
#=============文件上传========#
# 文件访问路径
file.path=/upload/**
# 静态资源文件访问路径
file.staticPath=/upload
#文件保存的绝对路径
file.address=f://springbootimage/
#是否支持 multipart 上传文件
spring.servlet.multipart.enabled=true
#最大支持文件大小
spring.servlet.multipart.max-file-size=30MB
#最大支持请求大小
spring.servlet.multipart.max-request-size=30MB

3 导入spring-boot文件配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;

/**
* @Description
* @Autor 伍军
* @Date 2021/10/13 16:31
* @Version 1.0
**/
@Configuration
public class UploadConfig implements WebMvcConfigurer {
@Value("${file.path}")
private String path;

@Value("${file.address}")
private String address;

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(path).addResourceLocations("file:" + address);
}
}

文件上传

1 创建文件信息表

1
2
3
4
5
6
7
DROP TABLE IF EXISTS `my_file`;
CREATE TABLE `my_file` (
`file_id` int(11) NOT NULL AUTO_INCREMENT,
`file_name` varchar(100) DEFAULT NULL,
`file_url` varchar(100) DEFAULT NULL,
PRIMARY KEY (`file_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2 创建文件上传列表界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">

<script type="text/javascript" src="/js/jquery-3.1.1.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/vue.js"></script>
</head>
<body>
<div id="myApp">
<a class="btn btn-primary btn-sm" @click="add">文件新增</a>

<table class="table">
<th>编号</th>
<th>文件名</th>
<th>下载路径</th>
<th>操作</th>
<tbody>
<tr v-for="x in list">
<td>{{x.fileId}}</td>
<td>{{x.fileName}}</td>
<td>{{x.fileUrl}}</td>
<td>
<button class="btn btn-success btn-sm" type="button" @click="download(x)">文件下载</button>
</td>
</tr>
</tbody>
</table>

<!-- 模态框开始 -->
<div id="one" class="modal fade" style="top:200px">
<div class="modal-dialog">

<div class="modal-content">
<!--头部-->
<div class="modal-header" >
<h4 align="center" >文件上传</h4>
</div>
<!--主题内容-->
<div class="modal-body">
<form role="form" class="form-horizontal">
<div class="form-group">
<label class=" col-sm-2 control-label">文件名</label>
<div class=" col-sm-10">
<input type="text" class="form-control" v-model="myfile.fileName" placeholder="请输入文件名">
</div>
</div>
<div class="form-group">
<label class=" col-sm-2 control-label">文件路径</label>
<div class=" col-sm-10">
<input type="text" class="form-control" v-model="myfile.fileUrl" >
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">选中文件</label>
<div class=" col-sm-10">
<form id="uploadForm">
<!-- multiple="multiple" 文件上传属性设置
ref="inputer vue中获取文档节点
-->
<input type="file" multiple="multiple" ref="inputer">
<input type="button" value="上传" @click="doUpload()" />
</form>
</div>
</div>
</form>
</div>

<!--底部-->
<div class="modal-footer">
<button class="btn btn-primary btn-sm" type="button" @click="closeWin()">关闭</button>
<button class="btn btn-primary btn-sm" type="button" @click="saveFile()" >保存</button>
</div>

</div>
</div>
</div>

</div>
</body>

3 定义相关js方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<script>
new Vue({
el:"#myApp",
data:{
myfile:{
fileUrl:"",
fileName:""
},
formData: new FormData(),//文件上传需要的对象
file: {}, //文件数据
list:[],//文件列表
},
methods:{
add:function () {//文件新增
//显示模态框
$("#one").modal("show");
},
doUpload:function () {//文件上传

//获取文件input元素节点
var inputDOM = this.$refs.inputer;
// 通过DOM取文件数据
this.file = inputDOM.files[0];
//将file属性添加到formData里
this.formData.append("files",this.file);

var self = this;
$.ajax({
url: '/file/upload' ,
type: 'POST',
data: self.formData,
contentType: false,
processData: false,//设置为false,data设置的数据会被序列化
success: function (data) {
console.log(data)
alert(data.info)
if(data.info=="上传成功"){
//数据回显文件名
self.myfile.fileName=self.file.name;
//数据回显文件的服务器下载路径
self.myfile.fileUrl=data.url;
}

}
});
},
closeWin:function () {// 关闭模态框
$("#one").modal("hide");
},
saveFile:function () {//保存
var self = this;
$.ajax({
url: '/file/add' ,
type: 'get',
data: self.myfile,
success: function (data) {
console.log(data)
alert(data.info)
if(data.info=="保存成功"){
//关闭模态框
$("#one").modal("hide");
//刷新
self.loadData();

}

}
});
},
loadData:function () {//加载数据表格
var self = this;
$.ajax({
url: '/file/list' ,
type: 'get',
dataType:"json",
success: function (data) {
console.log(data)
if(data.info!=false){
self.list=data.info
}

}
});
}

},
mounted(){
this.loadData();
}
})

</script>

4 在service层定义 文件上传接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* @Description
* @Autor 伍军
* @Date 2021/10/13 16:34
* @Version 1.0
**/
public interface MyFileService {

//文件上传
HashMap<String,Object> upload(MultipartFile file, HttpServletRequest request);
//文件新增
HashMap<String,Object> add(MyFile myfile);
// 文件列表
HashMap<String,Object> list();

}

5 定义service实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* @Description
* @Autor 伍军
* @Date 2021/10/13 16:35
* @Version 1.0
**/
@Service
public class MyFileServiceImpl implements MyFileService {

//注入上传文件的绝对物理目录路径
@Value("${file.address}")
private String fileAddres;

//注入访问上传文件的静态资源路径
@Value("${file.staticPath}")
private String fileStaicPath;

@Autowired(required = false)
private MyFileMapper myFileMapper;

@Override
public HashMap<String, Object> upload(MultipartFile file, HttpServletRequest reques) {

HashMap<String, Object> map=new HashMap<String, Object> ();
//记录图片后缀
String prefix="";
//记录当天日期
String dateStr="";
try{
if(file!=null){
//获取上传图片的后缀
String originalName = file.getOriginalFilename();
prefix=originalName.substring(originalName.lastIndexOf(".")+1);

//生成随机一个uuid字符串作为上传图片的名称,保持图片名称的唯一性
String uuid = UUID.randomUUID()+"";
//获取当天日期作为上传图片的上一级目录
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateStr = simpleDateFormat.format(date);
//得到上传文件的全路径
String filepath = fileAddres+"\\" + dateStr+"\\"+uuid+"." + prefix;
//打印查看上传路径
System.out.println(filepath);

File files=new File(filepath);
//判读目录是否存在,不存在就创建
if(!files.isDirectory()){
files.mkdirs();
}
//上传图片
file.transferTo(files);
//记录图片在项目中的路径,状态码,并传到前端
map.put("url",fileAddres+"/"+ dateStr+"/"+uuid+"." + prefix);
map.put("info","上传成功");
}

}catch (Exception e){
e.printStackTrace();
map.put("info","上传失败");;
}
return map;

}

@Override
public HashMap<String, Object> add(MyFile myfile) {
HashMap<String, Object> map = new HashMap<String, Object>();
int num = myFileMapper.insert(myfile);
if(num>0){
map.put("info","保存成功");
}else{
map.put("info","保存失败");
}
return map;
}

}

6 控制层代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* @Description
* @Autor 伍军
* @Date 2021/10/13 16:32
* @Version 1.0
**/
@Controller
@RequestMapping("/file")
public class MyFileController {

@Autowired
MyFileService fileService;
//文件上传
@RequestMapping("/upload")
@ResponseBody
public HashMap<String,Object> upload(@RequestParam("files")MultipartFile file, HttpServletRequest request){

return fileService.upload(file,request);
}
//文件 新增
@RequestMapping("/add")
@ResponseBody
public HashMap<String,Object> add(MyFile myFile){
return fileService.add(myFile);
}
//文件列表
@RequestMapping("/list")
@ResponseBody
public HashMap<String,Object> list(){
return fileService.list();
}

}

文件下载

1 给文件下载按钮添加 事件和函数

1
2
3
download:function (x) {
window.location.href="/file/download?fileUrl="+x.fileUrl+"&fileName="+x.fileName;
}

2 添加service 接口的文件下载方法

1
2
//文件下载
ResponseEntity<byte[]> downLoad(String fileUrl,String fileName, HttpServletRequest request) throws IOException;

3 实现类的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public ResponseEntity<byte[]> downLoad(String fileUrl,String fileName, HttpServletRequest request) throws IOException {

//创建下载文件对象
File file = new File(fileUrl);
//下面开始设置HttpHeaders,使得浏览器响应下载
HttpHeaders headers = new HttpHeaders();
// 设置响应方式
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//设置响应头
//new String(fileName.getBytes("utf-8"),"ISO8859-1") 是解决中文文件名下载 变成下划线的问题
try {
headers.set("Content-Disposition","attachment;filename="+new String(fileName.getBytes("utf-8"),"ISO8859-1")+"");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 把文件以二进制形式写回
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);

}

3 控制层方法

1
2
3
4
5
6
7
8
9
10
//文件下载
@RequestMapping("/download")
public ResponseEntity<byte[]> download(String fileUrl,String fileName, HttpServletRequest request){
try {
return fileService.downLoad(fileUrl,fileName,request);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
其他文章
cover
  • 25/09/27
  • 15:00
  • 284
  • 1
目录导航 置顶
  1. 1. title: 06-spring-boot-文件上传下载categories: springboot
  • 环境准备
  • 文件上传
  • 文件下载