首页 > 其他分享 >SpringBoot:SpringBoot集成Minio+KkFileView实现所有文档格式预览功能

SpringBoot:SpringBoot集成Minio+KkFileView实现所有文档格式预览功能

时间:2024-11-12 10:46:37浏览次数:1  
标签:Minio return String objectName param bucketName KkFileView public SpringBoot

前言

博主做项目时,存储文件使用的是Minio,各类格式文件都有(图片,pdf,word,excel等等),因为项目需求这些文档能进行预览,全部交给前端实现需要各种组件支撑,这无疑会加大前端的开发量,所以博主在网上搜索大量解决方法,最终找到这种可以实现方案

具体的kkFileView的介绍和部署可以看我的另一篇文章:https://www.cnblogs.com/nhdlb/p/18541242

pom文件

<dependencies>
    <!--  springWeb依赖  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <scope>provided</scope>
        <optional>true</optional>
    </dependency>
    <!--  minio依赖  -->
    <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
    </dependency>
    <!--  lombok依赖  -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

配置信息

minio:
  endpoint: http://*.*.*.*:9000/
  access-key: -------------------
  secret-key: ---------------------------------------
  bucket-name: portal-platform
  ## 自定义配置Https访问路径的参数
  httpConf: https://*.*.*:10000/minio/

# 文件预览软件访问路径
kkfileview:
  # 访问地址
  server: https://*.*.*:10000/kkfileview/
  # 单文件预览-路径拼接
  single: onlinePreview
  # 多图片预览-路径拼接
  images: picturesPreview

工具类

kkfileview配置类

@Component
@ConfigurationProperties(prefix = "kkfileview")
public class KkfileviewProperties {

    // IP访问路径
    private String server;
    // 单文件预览-路径拼接
    private String single;
    // 多图片预览-路径拼接
    private String images;

    public void setServer(String server) {
        this.server = server;
    }

    public void setSingle(String single) {
        this.single = single;
    }

    public void setImages(String images) {
        this.images = images;
    }

    public String getServer() {
        return server;
    }

    public String getSingle() {
        return single;
    }

    public String getImages() {
        return images;
    }
}

minio配置类

@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

    private String endpoint;

    private String accessKey;

    private String secretKey;

    private String bucketName;
    // 自定义配置Https访问路径的参数
    private String httpConf;

    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getAccessKey() {
        return accessKey;
    }

    public void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }

    public String getHttpConf() {
        if(httpConf.charAt(httpConf.length()-1) != '/'){
            return httpConf+"/";
        }
        return httpConf;
    }

    public void setHttpConf(String httpConf) {
        this.httpConf = httpConf;
    }
}

minio链接注入Bean

@Configuration
public class MinioConfiguration {

    @Resource
    private MinioProperties minioProperties;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(minioProperties.getEndpoint())
                .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
                .build();
    }

    @Bean
    public String currentMinioBucketName() {
        return minioProperties.getBucketName();
    }

}

Minio工具类

@Service
public class MinioService {

    @Resource
    private MinioClient minioClient;

    @Resource
    private String bucketName;

    /**
     * 判断存储桶是否存在
     *
     * @return boolean
     */
    @SneakyThrows
    public boolean isBucketExists() {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    /**
     * 创建存储桶
     */
    @SneakyThrows
    public void createBucket() {
        if (!isBucketExists()) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    @SneakyThrows
    public List<Item> getFolderItems(String folderPath) throws Exception {
        Iterable<Result<Item>> objects = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(bucketName)
                .prefix(folderPath)
                .recursive(true)
                .build());
        for (Result<Item> object : objects) {
            Item item = object.get();
            System.out.println("item.objectName() = " + item.objectName());
//            if (item.isDir() && item.objectName().replace("/", "").equals(dirName)) {
//                exists = true;
//            }
        }
        return null;
    }

    /**
     * 判断目录是否存在
     *
     * @param dirName 目录名称
     * @return boolean
     */
    @SneakyThrows
    public boolean isDirExists(String dirName) {
        boolean exists = false;

        Iterable<Result<Item>> objects = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(bucketName)
                .prefix(dirName)
                .recursive(false)
                .build()
        );

        for (Result<Item> object : objects) {
            Item item = object.get();
            System.out.println("item.objectName() = " + item.objectName());
            if (item.isDir() && item.objectName().replace("/", "").equals(dirName)) {
                exists = true;
            }
        }

        return exists;
    }

    /**
     * 判断文件是否存在
     *
     * @param objectName
     * @return
     */
    public boolean isObjectExists(String objectName) {
        try {
            minioClient.statObject(StatObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .build()
            );

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取文件流
     *
     * @param objectName 文件名
     * @return 二进制流
     */
    @SneakyThrows
    public InputStream getObject(String objectName) {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 断点下载
     *
     * @param objectName 文件名称
     * @param offset     起始字节的位置
     * @param length     要读取的长度
     * @return 二进制流
     */
    @SneakyThrows
    public InputStream getObject(String objectName, long offset, long length) {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .offset(offset)
                        .length(length)
                        .build());
    }

    /**
     * 使用MultipartFile进行文件上传
     *
     * @param file        文件名
     * @param objectName  对象名
     * @param contentType 类型
     * @return ObjectWriteResponse
     */
    @SneakyThrows
    public ObjectWriteResponse uploadFile(MultipartFile file, String objectName, String contentType) {
        InputStream inputStream = file.getInputStream();
        try {
            return minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(inputStream, inputStream.available(), -1)
                            .build());
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    /**
     * 使用File进行文件上传
     *
     * @param file        文件名
     * @param objectName  对象名
     * @param contentType 类型
     * @return ObjectWriteResponse
     */
    @SneakyThrows
    public ObjectWriteResponse uploadFile(File file, String objectName, String contentType) {
        InputStream inputStream = new FileInputStream(file);
        try {
            return minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(inputStream, inputStream.available(), -1)
                            .build());
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    /**
     * 上传本地文件
     *
     * @param objectName 对象名称
     * @param fileName   本地文件路径
     * @return ObjectWriteResponse
     */
    @SneakyThrows
    public ObjectWriteResponse uploadFile(String objectName, String fileName) {
        return minioClient.uploadObject(
                UploadObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .filename(fileName)
                        .build());
    }

    /**
     * 通过流上传文件
     *
     * @param objectName  文件对象
     * @param inputStream 文件流
     * @return ObjectWriteResponse
     */
    @SneakyThrows
    public ObjectWriteResponse uploadFile(String objectName, InputStream inputStream) {
        return minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(inputStream, inputStream.available(), -1)
                        .build());
    }

    /**
     * 创建文件夹或目录
     *
     * @param objectName 目录路径
     * @return ObjectWriteResponse
     */
    @SneakyThrows
    public ObjectWriteResponse createDir(String objectName) {
        return minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
                        .build());
    }

    /**
     * 获取文件信息, 如果抛出异常则说明文件不存在
     *
     * @param objectName 文件名称
     * @return String
     */
    @SneakyThrows
    public String getFileStatusInfo(String objectName) {
        return minioClient.statObject(
                StatObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build()).toString();
    }

    /**
     * 拷贝文件
     *
     * @param objectName    文件名
     * @param srcBucketName 目标存储桶
     * @param srcObjectName 目标文件名
     */
    @SneakyThrows
    public ObjectWriteResponse copyFile(String objectName, String srcBucketName, String srcObjectName) {
        return minioClient.copyObject(
                CopyObjectArgs.builder()
                        .source(CopySource.builder().bucket(bucketName).object(objectName).build())
                        .bucket(srcBucketName)
                        .object(srcObjectName)
                        .build());
    }

    /**
     * 文件移动
     * @param objectName 旧文件名
     * @param newObjectName 新文件名
     */
    @SneakyThrows
    public void moveFile(String objectName, String newObjectName) {
        copyFile(objectName, bucketName, newObjectName);
        removeFile(objectName);
    }

    /**
     * 删除文件
     *
     * @param objectName 文件名称
     */
    @SneakyThrows
    public void removeFile(String objectName) {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 获取有效时长的文件外链
     *
     * @param objectName 文件名
     * @param expires    过期时间 <=7 秒 (外链有效时间(单位:秒))
     * @return url
     */
    @SneakyThrows
    public String getPreSignedObjectUrl(String objectName, Integer expires) {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .expiry(expires)
                .bucket(bucketName)
                .object(objectName)
                .method(Method.GET)
                .build();
        return minioClient.getPresignedObjectUrl(args);
    }

    /**
     * 获得永不失效的文件外链
     *
     * @param objectName 对象名称
     * @return url
     */
    @SneakyThrows
    public String getPublicObjectUrl(String objectName) {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .method(Method.GET)
                .build();

        URI uri = new URI(minioClient.getPresignedObjectUrl(args));
        String path = uri.getPath().replaceAll("//", "/");
        return new URI(uri.getScheme(), uri.getAuthority(), path, null, null).toString();
    }

}

生成访问链接

@RestController
@RequestMapping("/sysfile")
@RequiredArgsConstructor
public class SysFileController {
    
    // Minio工具类
    private final MinioService minioService;
    // Minio配置文件
    private final MinioProperties minioProperties;
    // Kkfileview配置文件
    private final KkfileviewProperties kkfileviewProperties;
    
    /**
     * 上传文件
     *
     * @param file 文件
     * @param type
     * @return {@link String}
     */
    @Operation(summary = "文件上传")
    @GetMapping("/file/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        String url = null;
        try {
            // 文件名
            String filename = file.getOriginalFilename();
            // minio 上传文件
            ObjectWriteResponse objectWriteResponse = minioService.uploadFile(file, filename, file.getContentType());
            // 获得永不失效的文件外链
            url = minioService.getPublicObjectUrl(objectWriteResponse.object());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }
    
    /**
     * 文件预览
     * @param url minio文件外链
     */
    @Operation(summary = "文件预览")
    @GetMapping("/file/preview")
    public String previewFile(@RequestParam("url") String url) {
        return kkfileviewProperties.getServer() + kkfileviewProperties.getSingle() + "?url="
                + URLEncoder.encode(url, StandardCharsets.UTF_8);
    }

}

完成!!!!

 

标签:Minio,return,String,objectName,param,bucketName,KkFileView,public,SpringBoot
From: https://www.cnblogs.com/nhdlb/p/18541376

相关文章

  • Springboot计算机毕业设计家政服务预订系统z2tbn
    Springboot计算机毕业设计家政服务预订系统z2tbn本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,家政人员,家政类型,家政订单,关于我们开题报告内容一、项目背景与意义随着现代生活节奏的加......
  • Springboot计算机毕业设计驾校信息管理系统c6oor
    Springboot计算机毕业设计驾校信息管理系统c6oor本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:学员,教练,车辆信息,学员信息,我的预约,调度信息,车辆类型开题报告内容一、项目背景与意义随着交......
  • Springboot计算机毕业设计驾校预约管理系统5y0y2
    Springboot计算机毕业设计驾校预约管理系统5y0y2本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,教练,课程信息,驾校项目,报名信息,车辆信息,报修信息,维修信息,预约练车开题报告内容一、项目......
  • SpringBoot小区蔬菜直销系统12x8w 程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:用户,商品分类,商品信息开题报告内容一、研究背景随着居民生活水平的提高和健康意识的增强,小区居民对新鲜、安全、便捷的蔬菜需求日益增长。传统的蔬......
  • SpringBoot小葡萄雪糕贩卖机管理系统odx30 带论文文档1万字以上
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容;用户,雪糕信息,雪糕排行,订单信息开题报告内容一、选题背景与意义随着科技的飞速发展和消费者需求的日益多元化,智能零售已成为现代商业的重要趋势。......
  • SpringBoot线上书城网站h5z49 程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:用户,图书类型,热卖图书开题报告内容一、课题背景与意义随着互联网技术的快速发展,电子商务已成为现代商业活动的重要组成部分。线上书城作为电子商务......
  • SpringBoot闲置物品置换平台u3ptr 带论文文档1万字以上,文末可获取
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:会员,卖家,物品分类,闲置物品,交易信息,求购信息开题报告内容一、研究背景与意义随着物质生活的丰富和消费观念的转变,人们手中积累的闲置物品日益增......
  • Springboot计算机毕业设计家政服务管理系统etuwq
    Springboot计算机毕业设计家政服务管理系统etuwq本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,员工,会员档案,家政档案,服务分类,服务项目,预约服务,订单评价,家政人员开题报告内容一、项目......
  • Springboot计算机毕业设计家政服务网fs6h1
    Springboot计算机毕业设计家政服务网fs6h1本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:家政公司,家政人员,家政类型,招聘信息,应聘信息,用户,评价信息开题报告内容一、项目背景与意义随着现代......
  • Docker:部署kkFileView所有格式文档在线预览服务
    前言kkFileView是一个文档在线预览服务,基本支持主流文档格式预览,目前支持的文件类型如下:支持doc,docx,xls,xlsx,xlsm,ppt,pptx,csv,tsv,dotm,xlt,xltm,dot,dotx,xlam,xla等Office办公文档支持wps,dps,et,ett,wpt等国产WPSOffice办公文档支持odt,......