后端使用springboot
1.pom文件依赖:添加web和lombok依赖,也可以只添加web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.在application.yml中指定文件上传路径(根据电脑实际情况修改即可)
# 文件上传
file:
uploadFilePath: E:/file/upload/
3.新建工具包util,新建类R作为统一返回值
@Data
public class R<T> implements Serializable {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private T data; //数据
private Map map = new HashMap(); //动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.data = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String msg) {
R r = new R();
r.msg = msg;
r.code = 0;
return r;
}
public R<T> add(String key, Object value) {
this.map.put(key, value);
return this;
}
}
4.编写controller
@RestController
@RequestMapping("/file")
public class FileController {
@Value("${file.uploadFilePath}")
String folder;//文件存放路径
@PostMapping("/upload")
public R fileUpload(HttpServletRequest req, MultipartFile file) {
//获取文件路径
String originalFilename = file.getOriginalFilename();//获取文件名
//判断文件是否有效 截取看大小和扩展名是否存在
if (file.getSize() == 0) {
return R.error("文件无效");
}
//文件扩展名是否存在
String expandedName = originalFilename.substring(originalFilename.lastIndexOf("."));
if (expandedName == null) {
return R.error("文件无效");
}
//创建文件夹 根据时间 每天为一个文件夹
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String folderLastPath = sdf.format(new Date());//文件夹后缀
String folderPath = folder + folderLastPath;//文件夹全路径
//判断文件夹是否存在
//创建文件夹前判断文件夹是否存在
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdirs();//不存在 新建一个文件夹
}
//全路径文件名
String realPath = folderPath + "/" + originalFilename;
try {
//判断文件夹内是否存在同名的文件
File file1 = new File(realPath);
if (file1.exists()) {//文件已经存在
//修改文件名
//获取文件名 shhs.doc中的shhs
String fileRealName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
String kuozhanName = originalFilename.substring(originalFilename.lastIndexOf("."));
//将真是名字设置为(1)后拼接上扩展名
fileRealName = fileRealName + "(1)";
originalFilename = fileRealName + kuozhanName;
//创建文件
file.transferTo(new File(folder, originalFilename));
realPath = folderPath + "/" + originalFilename;
return R.success(realPath);
}
//文件不存在 创建文件
file.transferTo(new File(folder, originalFilename));
} catch (IOException e) {
throw new RuntimeException(e);
}
return R.success(realPath);
}
}
5.使用postman进行测试(也可以不用,直接写前端测试)
新建post请求-->输入地址-->选择Body-->选择form-data-->输入file-->在file的行末有一个选项,下拉是文本和file,选择file -->选择文件后发送即可
前端:采用vue+elementUI
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords"
content="Flat Dark Web Login Form Responsive Templates, Iphone Widget Template, Smartphone login forms,Login form, Widget Template, Responsive Templates, a Ipad 404 Templates, Flat Responsive Templates"/>
<!--引入vue.js核心库-->
<script src="js/vue.js"></script>
<!--引入elementUI-->
<script src="element-ui/lib/index.js"></script>
<!--引入axios.js-->
<!--axios没用到 可以不引-->
<!-- <script src="js/axios-0.18.0.js"></script>-->
<!--引入css-->
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<!--判断elementUI是否导入成功-->
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-upload
action="/upload"
:on-preview="handlePreview"
:limit="100"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传pdf文件 最大值为100M</div>
</el-upload>
</div>
<script>
new Vue({
el: '#app',
data() {
return {}
},
methods: {
handlePreview(file) {
window.open(file.response.url)
}
},
mounted() {
}
})
</script>
</body>
</html>
文件下载使用的是浏览器提供的功能,在新窗口打开,pdf等可以预览和下载,图片等直接下载
前后端分离需要解决跨域问题
不足之处:
如果上传的文件在文件夹中已存在,则会自动在后面拼上(1),如abc.docx已存在,则会变成abc(1).docx
但是如果再传一个abc.docx,则原来的abc(1).docx会被覆盖
可以通过判断数量来不断新增,写起来麻烦,就没有写了,希望对大家有所帮助!!!