概述
文件上传与下载,是程序开发中经常使用到的一个功能,比如:
- 用户头像、文章封面等需求
- 博客中发布文章的富文本编辑框插件文件上传功能
- …
什么是文件上传?文件上传就是为了共享资源,
一句话:把用户的自己电脑中的文件,通过程序上传到服务器的过程
如何实现
新建一个spring boot工程
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
</dependencies>
配置文件
server:
port: 8080
spring:
freemarker:
suffix: .html
cache: false
servlet:
multipart:
enabled: true # 开启文件上传
file-size-threshold: 2KB # 文件写入磁盘的阈值
max-file-size: 100MB
max-request-size: 215MB # 最大请求值大小
# 自定义文件保存路径
gorit:
file:
root:
path: E:\桌面\test\
controller
package com.example.demo.controller;
import com.example.demo.R.Result;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Api(value = "文件上传,下载相关功能")
@RestController
public class FileController {
// 设置固定的日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 将 yml 中的自定义配置注入到这里
@Value("${gorit.file.root.path}")
private String filePath;
// 日志打印
private Logger log = LoggerFactory.getLogger("FileController");
// 文件上传 (可以多文件上传)
@PostMapping("/upload")
public Result fileUploads(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
// 得到格式化后的日期
String format = sdf.format(new Date());
// 获取上传的文件名称
String fileName = file.getOriginalFilename();
// 时间 和 日期拼接
String newFileName = format + "_" + fileName;
// 得到文件保存的位置以及新文件名
File dest = new File(filePath + newFileName);
try {
// 上传的文件被保存了
file.transferTo(dest);
// 打印日志
log.info("上传成功,当前上传的文件保存在 {}",filePath + newFileName);
// 自定义返回的统一的 JSON 格式的数据,可以直接返回这个字符串也是可以的。
return Result.succ("上传成功");
} catch (IOException e) {
log.error(e.toString());
}
// 待完成 —— 文件类型校验工作
return Result.fail("上传错误");
}
}
返回的R类(统一返回和处理)
package com.example.demo.R;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
private Object data;
private String msg;
private int code;
// 操作成功返回数据
public static Result succ(Object data) {
return succ(200, "操作成功", data);
}
public static Result succ(String msg) {
return succ(200, msg, null);
}
public static Result succ(int code, String msg, Object data) {
Result r = new Result();
r.setCode(code);
r.setMsg(msg);
r.setData(data);
return r;
}
public static Result succ(String msg, Object data) {
return succ(200,msg,data);
}
// 操作异常返回
public static Result fail(int code, String msg, Object data) {
Result r = new Result();
r.setCode(code);
r.setMsg(msg);
r.setData(data);
return r;
}
public static Result fail(String msg) {
return fail(400,msg,null);
}
public static Result fail(int code, String msg) {
return fail(code,msg,"null");
}
public static Result fail(String msg, Object data) {
return fail(400,msg,data);
}
}
设置静态资源的路径
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 开启 mvc支持,设置 static 目录为类路径
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 得到 classpath 的根路径, resources 目录下的所以路径都可以得到
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
静态页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<form action="/upload" enctype="multipart/form-data" method="post">
<input name="dir" value="bbs">
<input name="file" type="file">
<input type="submit" value="文件上传">
</form>
<br><br><br><br>
<h1>文件下载</h1>
<a href="http://localhost:8080/data/demo.html" download="demo.html">点击下载</a>
</body>
</html>
运行测试
访问路径http://localhost:8080/index
文件上传
(请忽略它的丑。。。毕竟只是个小测试)
文件下载
文件下载是访问的我们springboot项目当中的静态资源目录,默认在resource的static目录下,也可以通过上面的配置类进行更改静态资源的目录
关于文件下载:
<h1>文件下载</h1>
<a href="http://localhost:8080/data/demo.html" download="demo.html">点击下载</a>
</body>
a标签的href
在前后端分离项目中,需填写服务器的完整访问接口
在springboot单体项目中,配置了freemarker或thymeleaf模板引擎,可以填写href="data/demo.html"
写在最后
这是我目前见过的实现springboot文件上传功能比较简单的实现方式,写起来非常简洁易懂,若有问题欢迎指正与讨论😁