springboot集成kkFileView + minio实现文件上传并预览(带源码)
一、minio部署
minio部署见我的上一篇文章:
链接: https://blog.csdn.net/asdfggfdsa121/article/details/141635922
二、kkFileView部署
下载kkFileView文件(源码 + 打包好的文件):
链接:https://pan.baidu.com/s/1m3_sMoMrWcSs3iH4WODZ_Q?pwd=p43r
1.直接部署, 不涉及源码
解压文件, 到达如下路径
输入启动命令, 启动kkFileView项目
java -jar kkFileView-4.4.0-SNAPSHOT.jar
启动完成如下图
访问: localhost:8012, 进入如下页面, 说明部署成功
2.源码启动
用idea打开如下文件夹
用maven下载相关依赖, 编译并启动, 启动成功同样访问: localhost:8012, 如需修改端口请自行到配置文件修改
三、通过minio生成的url实现在线文档预览
注意: 此处用两种minio上传的方式, 来说明minio+kkFileView实现文件上传预览, 本文主要讲解KKFileView, 两种minio上传方式详情请见我的上一篇文章, 链接在文章开头
1.minio通过原生的MinioClient上传文件生成的url
原生MinioClient上传代码(如需获取upload上传源码请见我的上一篇文章, 链接在文章开头)
/**
* 文件上传
* @param file
* @return
*/
public Map<String, String> upload(MultipartFile file) {
String filename = FileUtils.extractUploadFilename(file);
String url = null;
try {
InputStream inputStream = file.getInputStream();
// 上传到minio服务器
minioClient.putObject(PutObjectArgs.builder()
.bucket(this.bucketName)
.object(filename)
.stream(inputStream, -1L, 10485760L)
.build());
url = minioClient.getObjectUrl("test", filename);
} catch (Exception e) {
e.printStackTrace();
}
// 返回地址
Map<String,String> resultMap = new HashMap<>();
resultMap.put("url",url);
return resultMap;
}
粘贴到如下, 在线文档预览地址框中
预览正常
2.通过AmazonS3上传文件到minio
AmazonS3上传文件
@Override
public Map<String, Object> uploadFile(MultipartFile file) {
if (file.isEmpty()) {
throw new RuntimeException("文件为空");
}
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(file.getContentType());
objectMetadata.setContentLength(file.getSize());
String key = IdUtil.getSnowflakeNextIdStr();
if(!amazonS3.doesBucketExistV2(minioProperties.getBucket())){
amazonS3.createBucket(minioProperties.getBucket());
}
try {
PutObjectResult putObjectResult = amazonS3.putObject(new PutObjectRequest(minioProperties.getBucket(), key, file.getInputStream(), objectMetadata));
if (putObjectResult != null) {
Date expiration = new Date();
long expirTime = expiration.getTime();
expirTime += 1000 * 60 * 60 * 24 * 365 * 10;
expiration.setTime(expirTime);
GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(minioProperties.getBucket(), key).withExpiration(expiration);
URL url = amazonS3.generatePresignedUrl(urlRequest);
String fileName = file.getName();
String fileUrl = minioClient.getObjectUrl("test", fileName);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("url", url);
resultMap.put("fileUrl", fileUrl);
resultMap.put("fileSize", file.getSize());
resultMap.put("fileId", key);
return resultMap;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
返回的url如下所示(此处wholeUrl为完整的url)
同样将wholeUrl粘贴到文件预览框中测试, 发现无法解析
kkfileview后台报错如下
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-5.3.3.jar:5.3.3]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.3.jar:5.3.3]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.3.jar:5.3.3]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791) ~[jetty-servlet-9.4.35.v20201120.jar:9.4.35.v20201120]
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626) ~[jetty-servlet-9.4.35.v20201120.jar:9.4.35.v20201120]
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:228) ~[websocket-server-9.4.35.v20201120.jar:9.4.35.v20201120]
........
... 75 common frames omitted
经过排查只需要在url后加上如下参数即可解决
&fullfilename=你的文件名 #注意文件名为完整文件名, 包含后缀
访问如下url, 成功预览!
http://localhost:9000/test/1827991737789026304AWSAccessKeyId=minioadmin&Expires=1726489555&Signature=I8xpzEddxnrs%2FQlxih%2F%2F9lrva%2BQ%3D&fullfilename=副本测点维护(1).xlsx
四、前端整合
- 原生minio
//要预览文件的访问地址
var url = 'http://localhost:9000/test/2024/08/26/%E5%89%AF%E6%9C%AC%E6%B5%8B%E7%82%B9%E7%BB%B4%E6%8A%A4%281%291724654219963.xlsx';
window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(url)));
- 通过AmazonS3上传到minio
//要预览文件的访问地址
var url = 'http://localhost:9000/test/1828005554510413824?AWSAccessKeyId=minioadmin&Expires=1726492849&Signature=KAzU1X60MwGg7bjNIJnok21N1ws%3D&fullfilename=副本测点维护(1).xlsx';
window.open('http://127.0.0.1:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url)));
因为使用AmazonS3上传到minio返回url有签名, 其实也就是会存在过期时间, 解决过期的办法就是直接不需要带url后面的签名, 只需要把?后面的一大串全部去掉, 然后加上 ?fullfilename=文件名 即可如下所示
//要预览文件的访问地址
var url = 'http://localhost:9000/test/1828005554510413824?fullfilename=副本测点维护(1).xlsx';
window.open('http://127.0.0.1:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url)));
完结撒花!
谢谢观看, 有问题请留言, 看到会回复!