ファイルのアップロードとダウンロード
Maven の依存関係
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
コード
ビジネスクラスのファイルコントローラー
package com.example.demo.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.Files;
import com.example.demo.mapper.FilesMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
@RestController
@RequestMapping("/file")
public class FilesController {
//获取项目路径
private static final String demoDirectory=new File("").getAbsolutePath();
//拼接文件存放目录
private static final String currentDirectory=demoDirectory+"\\src\\main\\resources\\image\\";
@Value("${server.ip:localhost}:${server.port}/${server.servlet.context-path:}")
private String server;
@Resource
FilesMapper filesMapper;
@PostMapping("/upload")
public String saveFile(@RequestBody MultipartFile file) throws IOException {
//文件大小(mb)
long size = file.getSize()/1024;
//文件名
String name = file.getOriginalFilename();
//根据文件名获取文件类型
String type= FileUtil.extName(name);
//定义一个文件唯一的表示码
String FileUUID=IdUtil.fastSimpleUUID()+StrUtil.DOT+type;
File uploadFile=new File(currentDirectory+FileUUID);
//获取文件目录
File parentFile=uploadFile.getParentFile();
//判断文件路径是否存在
if(!parentFile.exists()){
parentFile.mkdirs();
}
String url;
//获取文件的md5
String md5= SecureUtil.md5(file.getInputStream());
//从数据库查询md5是否有数据
Files dbFiles=getFileByMd5(md5);
if(dbFiles!=null){
url=dbFiles.getUrl();
}
else {
file.transferTo(uploadFile);
url="http://"+server+"file/"+ FileUUID;
}
Files files=new Files();
files.setName(name);
files.setMd5(md5);
files.setType(type);
files.setSize(size);
files.setUrl(url);
filesMapper.insert(files);
return url;
}
/**
* 文件下载
* @param FileUUID 文件名
* @param response
* @throws IOException
*/
@GetMapping("/{FileUUID}")
public void download(@PathVariable String FileUUID, HttpServletResponse response) throws IOException {
File uploadFile=new File(currentDirectory+FileUUID);
//设置输出流的格式
ServletOutputStream os=response.getOutputStream();
response.addHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(FileUUID,"TF-8"));
response.setContentType("application/octet-stream");
//写入流
os.write(FileUtil.readBytes(uploadFile));
//发送完成刷新管道
os.flush();
//关闭管道
os.close();
}
/**
* 获取数据库中的md5
* @param md5
* @return
*/
private Files getFileByMd5(String md5) {
QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("md5",md5);
List<Files> files = filesMapper.selectList(queryWrapper);
return files.size()==0? null: files.get(0);
}
}
データベーステーブルの設計
/*
Navicat Premium Data Transfer
Source Server : 我的远程服务器
Source Server Type : MySQL
Source Server Version : 80032 (8.0.32-0ubuntu0.22.04.2)
Target Server Type : MySQL
Target Server Version : 80032 (8.0.32-0ubuntu0.22.04.2)
File Encoding : 65001
Date: 22/05/2023 10:58:03
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_file
-- ----------------------------
DROP TABLE IF EXISTS `sys_file`;
CREATE TABLE `sys_file` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件名称',
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件类型',
`size` bigint NULL DEFAULT NULL COMMENT '文件大小(kb)',
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '下载链接',
`md5` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件md5',
`is_delete` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
`enable` tinyint(1) NULL DEFAULT 1 COMMENT '是否禁用链接',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 62 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
エンティティクラスファイル
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@TableName("sys_file")
public class Files {
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("文件名")
private String name;
@ApiModelProperty("文件类型")
private String type;
@ApiModelProperty("文件大小")
private Long size;
@ApiModelProperty("文件链接")
private String url;
@ApiModelProperty("文件的md5,用文件的输出流加密")
private String md5;
@ApiModelProperty("是否以删除文件")
private Boolean isDelete;
@ApiModelProperty("是否启用文件")
private Boolean enable;
}