Java后端实现文件的上传与下载
前言
在WEB应用开发过程中,文件的上传与下载功能可以说是基础必备的了,在这里就SpringBoot、Vue、Axios前后端分离的项目环境下,简单模拟一下通用的文件上传与下载需求的后端实现。
实现
所需依赖坐标
<!--MyBatis-Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--HuTool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M4</version>
</dependency>
上传接口
Contrroller
@PostMapping("/upload")
public Result<Boolean> save(MultipartFile file) throws IOException {
fileService.saveFile(file);
return Result.success("上传成功!");
}
Service
public interface FileService extends IService<Files> {
void saveFile(MultipartFile file) throws IOException;
}
ServiceImpl
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, Files> implements FileService {
@Autowired
private FileMapper fileMapper;
@Value("${files.upload.path}")
private String fileUploadPath;
@Value("${server.ip}")
private String serverIp;
@Value("${server.port}")
private String serverPort;
public Files getFileByMd5(String md5) {
// 查询文件的md5是否存在
QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("md5", md5);
List<Files> filesList = fileMapper.selectList(queryWrapper);
return filesList.size() == 0 ? null : filesList.get(0);
}
@Override
public void saveFile(MultipartFile file) throws IOException {
String originalFilename = "";
String type = "";
String originType = "";
String url = "";
long size = 0;
String md5 = "";
try {
originalFilename = file.getOriginalFilename(); // 获取原文件名称
type = FileUtil.extName(originalFilename); // 获取文件类型
size = file.getSize(); // 获取文件大小单位b
} catch (Exception e){
e.printStackTrace();
throw new ServerException("获取上传文件信息失败!");
}
try {
// 定义一个文件唯一的标识码
String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + originType;
File uploadFile = new File(fileUploadPath + fileUUID);
// 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
File parentFile = uploadFile.getParentFile();
if(!parentFile.exists()) {
parentFile.mkdirs();
}
// 获取上传原文件的md5
md5 = SecureUtil.md5(file.getInputStream());
// 从数据库查询是否存在相同的记录
Files dbFiles = getFileByMd5(md5);
if (dbFiles != null) {
url = dbFiles.getUrl();
} else {
// 上传文件到磁盘
file.transferTo(uploadFile);
// 数据库若不存在重复文件,则不删除刚才上传的文件
url = "http://" + serverIp + ":" + serverPort + "/files/" + fileUUID;
}
} catch (Exception e) {
e.printStackTrace();
throw new ServerException("文件持久化到服务器失败!" );
}
// 存储数据库
try {
Files saveFile = new Files();
saveFile.setFileName(originalFilename);
saveFile.setType(type);
saveFile.setSize(size/1024); // 单位 kb
saveFile.setUrl(url);
saveFile.setMd5(md5);
saveFile.setCreateTime(new Date());
ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
saveFile.setUserId(activeUser.getUser().getId());
saveFile.setDownloadCount(0L);
fileMapper.insert(saveFile);
}catch (Exception e){
e.printStackTrace();
throw new ServerException("保存文件到数据库失败!");
}
}
}
下载接口
Controller
@GetMapping("/download/{fileUUID}")
public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
// 根据文件的唯一标识码获取文件
File uploadFile = new File(fileUploadPath + fileUUID);
// 设置输出流的格式
ServletOutputStream os = response.getOutputStream();
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
response.setContentType("application/octet-stream");
// 读取文件的字节流
os.write(FileUtil.readBytes(uploadFile));
os.flush();
os.close();
}
微信关注
阅读剩余
版权声明:
作者:理想
链接:https://www.imyjs.cn/archives/830
文章版权归作者所有,未经允许请勿转载。
THE END