1.设计数据库
CREATE TABLE `timages` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建者',
`update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新者',
`remarks` VARCHAR(255) DEFAULT NULL COMMENT '描述',
`del_flag` VARCHAR(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '0' COMMENT '逻辑删除标记(0:显示;1:隐藏)',
`title` VARCHAR(255) DEFAULT NULL COMMENT '标题',
`url` VARCHAR(300) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '图片路径',
`img` VARCHAR(300) DEFAULT NULL COMMENT '图片名称',
`md5` VARCHAR(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '图片压缩',
`mtype` VARCHAR(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '图片类型',
`size` BIGINT DEFAULT NULL COMMENT '文件大小',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COMMENT='文档管理'
2.创建实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Images {
private Integer id;
private String createBy;
private String updateBy;
private String remarks;
private String delFlag;
private String title;
private String url;
private String img;
private String mtype;
private String md5;
private long size;
}
3.编写上传文件代码
添加依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
3.0编写yaml 设置上传文件的地址
file:
upload:
path: D:/SpringBoot/tiantianxitong/files/
3.1创建Controller层 定义上传文件方法
@RestController//控制层注解
@CrossOrigin //跨域请求注解
@RequestMapping("/file")//请求路径
public class FileController{
//获取磁盘路径
@Value("${file.upload.path}")
private String Fileupload;
@Resource
private FileMapper fileMapper;
@RequsetMapping("/upload")
public String fileUpload(@RequsetParam MultipartFile file){
String md5;
String url;
//获取原始文件名
String originalFilename = file.getOriginalFilename();
//获取文件类型
String type =FileUtil.exName(originalFilename);
//获取文件大小
long size =file.getSize();
//定义文件标识
String uuid = IdUtil.fastSimpleUUID();
//设置文件真实名称
String Fileuuid =uuid+StrUtil.Dot+type;
//实际存储
File realfile = new File(Fileupload+Fileuuid );
//获取正式名称的父级文件
File parentFile = realfile.getparentFile();
//判断父级文件是否存在
if(!parentFile.exists()){
//如果父级文件不存在就创建一个
parentFile.mkdirs();
}
//将文件存到磁盘
file.transferTo(realfile);
//查看文件的md5
md5=SecureUtil.md5(realfile);
//根据md5查询数据库
MyFile myfile =getFilemd5(md5);
//判断数据库中是否已经存在此文件
if(myfile!=null){
//文件已经存在
//将已有文件的url赋值给url
url = myfile.getURL();
//删除realfile做到文件压缩 不加这句代码 文件会重复出现在磁盘中
realfile.delete()
}else{
//如果不存在将Fileuuid赋值给url
url=Fileuuid;
}
//将数据放入实体类
MyFile saveFile = new MyFile();
saveFile.setUName(originalFilename);
saveFile.setType(type);
saveFile.setSize(size/1024);
saveFile.setUUrl(url);
saveFile.setMd5(md5);
//执行添加操作
fileMapper.insert(saveFile);
return url;
}
}
getFilemd5根据获取上传文件的md5判断是否和数据库重复代码如下
private MyFile getFilemd5(String md5){
//判断数据库md5是否存在 存在不存入磁盘 减少空间
QueryWrapper<MyFile> wrapper = new QueryWrapper<>();
wrapper.eq("md5",md5);
List<MyFile> myFiles = fileMapper.selectList(wrapper);
return myFiles.size()==0?null:myFiles.get(0);
}
然后到mapper层编写根据md5查找文件sql语句如下
<select id="selectImg" resultType="images">
select * from timages where md5=#{md5}
</select>
使用postman访问 http://localhost:1900/file/upload
返回一个url路径表示上传成功
在本地D:\SpringBoot\tiantianxitong\files 查看可以看到上传成功的图片而且压缩过后是没有重复,再查看数据库数据可以看到添加的重复数据已经被压缩。
4.下载文件代码
上面实现了文件上传下面就要实现文件的下载
4.1在Controller层中编写文件下载代码
@RestController
@RequestMapping("/file")
@CrossOrigin
public class FileController {
//文件上传
.......
//文件下载
@GetMapping("{Fileuuid}") //文件下载路径 使用RESTful风格传参
public void download(@PathVariable Fileuuid,HttpServletResponse res){
//根据Fileuuid获取文件
File realFile= new File(Fileupload+Fileuuid);
res.addHeader("Content-Disposition","attachment;filename="+
URLEncoder.encode(Fileuuid,"UTF-8"));
res.setContentType("application/octet-stream");
ServletOutputStream outputStream = res.getOutputStream();
//读取文件字节流
outputStream.write(FileUtil.readBytes(realFile));
outputStream.flush();
outputStream.close();
}
}
然后访问http://localhost:1900/file/69f54f888b6a4dc8a66474c07de94f8c.jpg
69f54f888b6a4dc8a66474c07de94f8c.jpg 为上传文件时返回的url
以上文件下载有错 在前端显示时候会报错
Failed to complete request: org.apache.catalina.connector.ClientAbortException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
正确代码如下:
//文件下载
@GetMapping("{Fileuuid}")
private void download(@PathVariable("Fileuuid") String Fileuuid, HttpServletResponse res) throws IOException {
//根据Fileuuid获取文件
File file = new File(Imagesfile+Fileuuid);
ServletOutputStream outputStream = res.getOutputStream();
res.addHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(Fileuuid,"UTF-8"));
res.setContentType("application/octect-stream");
//读取字节流
outputStream.write(FileUtil.readBytes(file));
outputStream.flush();
outputStream.close();
}
这样就可以显示成功了!!!