跳至主要內容

springboot整合minio

bug君大约 10 分钟

minio安装参考

1. 添加依赖

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>${minio.version}</version>
        </dependency>

2. 配置

2.1 yml配置minio相关信息

minio:
  endpoint: http://192.168.31.48:9000
  accessKey: root
  secretKey: root@123456!
  bucketName: test-bucket

2.2 配置类

/**
 * Minio 配置类
 *
 * @author zwj
 * @date 2024/02/01
 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    
    /**
     * 端点
     */
    private String endpoint;
    
    /**
     * 访问密钥
     */
    private String accessKey;
    
    /**
     * 密钥
     */
    private String secretKey;
    
    /**
     * 存储桶名称
     */
    private String bucketName;
    
    /**
     * Minio 客户端
     *
     * @return {@link MinioClient}
     */
    @Bean
    public MinioClient minioClient() {
        
        return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
        
    }
}

3. 工具类


/**
 * Minio 工具类
 *
 * @author zwj
 * @date 2024/02/01
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUtils {
    
    private final MinioConfig minioConfig;
    
    private final MinioClient minioClient;
    
    /**
     * 创建存储桶
     *
     * @param bucketName 存储桶名称
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     * @apiNote 如果
     */
    private void createBucket(String bucketName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        if (!bucketExists(bucketName)) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }
    
    /**
     * 存储桶存在 存储桶是否存在
     *
     * @param bucketName 存储桶名称
     * @return boolean
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public boolean bucketExists(String bucketName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }
    
    /**
     * 获取存储桶策略
     *
     * @param bucketName 存储桶名称
     * @return {@link String}
     * @throws ServerException               服务器异常
     * @throws InsufficientDataException     数据不足异常
     * @throws ErrorResponseException        错误响应异常
     * @throws BucketPolicyTooLargeException 存储桶策略过大异常
     * @throws IOException                   ioexception
     * @throws NoSuchAlgorithmException      没有这样算法例外
     * @throws InvalidKeyException           无效密钥异常
     * @throws InvalidResponseException      无效响应异常
     * @throws XmlParserException            XML 解析器异常
     * @throws InternalException             内部异常
     */
    public String getBucketPolicy(String bucketName)
            throws ServerException, InsufficientDataException, ErrorResponseException, BucketPolicyTooLargeException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
    }
    
    /**
     * 获取所有存储桶
     *
     * @return {@link List}<{@link Bucket}>
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public List<Bucket> getAllBuckets()
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.listBuckets();
    }
    
    /**
     * 根据桶名称获取其相关信息
     *
     * @param bucketName 存储桶名称
     * @return {@link Optional}<{@link Bucket}>
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public Optional<Bucket> getBucket(String bucketName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }
    
    /**
     * 删除桶
     *
     * @param bucketName 存储桶名称
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public void removeBucket(String bucketName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
    }
    
    
    /**
     * 判断文件是否存在
     *
     * @param bucketName 存储桶名称
     * @param objectName 文件
     * @return boolean
     */
    public boolean isObjectExist(String bucketName, String objectName) {
        
        boolean exist = true;
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            log.error("判断文件是否存在,出现异常:{}:", e.getMessage(), e);
            exist = false;
        }
        return exist;
    }
    
    /**
     * 判断文件夹是否存在
     *
     * @param bucketName 存储桶名称
     * @param folderName 文件夹
     * @return boolean
     */
    public boolean isFolderExist(String bucketName, String folderName) {
        
        boolean exist = false;
        try {
            Iterable<Result<Item>> results = minioClient.listObjects(
                    ListObjectsArgs.builder().bucket(bucketName).prefix(folderName).recursive(false).build());
            for (Result<Item> result : results) {
                Item item = result.get();
                if (item.isDir() && folderName.equals(item.objectName())) {
                    exist = true;
                }
            }
        } catch (Exception e) {
            log.error("判断文件夹是否存在出现异常{}:", e.getMessage(), e);
            exist = false;
        }
        return exist;
    }
    
    /**
     * 按前缀获取所有文件
     *
     * @param bucketName 存储桶
     * @param prefix     前缀
     * @param recursive  是否使用递归查询
     * @return MinioItem 列表
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        List<Item> list = new ArrayList<>();
        Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
        if (objectsIterator != null) {
            for (Result<Item> o : objectsIterator) {
                Item item = o.get();
                list.add(item);
            }
        }
        return list;
    }
    
    /**
     * 获取文件流
     *
     * @param objectName 文件名
     * @param bucketName 存储桶名称
     * @return 二进制流
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public InputStream getObject(String bucketName, String objectName)
            
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return minioClient.getObject(
                GetObjectArgs.builder().bucket(minioConfig.getBucketName()).object(objectName).build());
    }
    
    /**
     * 断点下载
     *
     * @param bucketName 存储桶
     * @param objectName 文件名称
     * @param offset     起始字节的位置
     * @param length     要读取的长度
     * @return 二进制流
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    
    public InputStream getObject(String bucketName, String objectName, long offset, long length)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.getObject(
                GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());
    }
    
    /**
     * 获取路径下文件列表
     *
     * @param bucketName 存储桶
     * @param prefix     文件名称
     * @param recursive  是否递归查找,false:模拟文件夹结构查找
     * @return 二进制流
     */
    public Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) {
        
        return minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
    }
    
    /**
     * 上传文件
     *
     * @param bucketName  存储桶
     * @param file        文件名
     * @param objectName  对象名
     * @param contentType 类型
     * @return {@link ObjectWriteResponse}
     * @throws IOException               ioexception
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName, String contentType)
            throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        InputStream inputStream = file.getInputStream();
        return minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType)
                        .stream(inputStream, inputStream.available(), -1).build());
    }
    
    /**
     * 上传图片
     *
     * @param bucketName  存储桶名称
     * @param imageBase64 图像 base64
     * @param imageName   图像名称
     * @return {@link ObjectWriteResponse}
     * @throws IOException               ioexception
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     * @apiNote 文件夹名称 年月
     */
    public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String imageName)
            throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        if (!StringUtils.isEmpty(imageBase64)) {
            InputStream in = base64ToInputStream(imageBase64);
            String newName = System.currentTimeMillis() + "_" + imageName + ".jpg";
            String year = String.valueOf(LocalDate.now().getYear());
            String month = String.valueOf(LocalDate.now().getMonth());
            return uploadFile(bucketName, year + "/" + month + "/" + newName, in);
            
        }
        return null;
    }
    
    /**
     * base64转为输入流
     *
     * @param base64 base64
     * @return {@link InputStream}
     */
    private static InputStream base64ToInputStream(String base64) throws IOException {
        
        ByteArrayInputStream stream = null;
        
        byte[] bytes = new BASE64Decoder().decodeBuffer(base64.trim());
        stream = new ByteArrayInputStream(bytes);
        
        return stream;
    }
    
    
    /**
     * 上传本地文件
     *
     * @param bucketName 存储桶
     * @param objectName 对象名称
     * @param fileName   本地文件路径
     * @return {@link ObjectWriteResponse}
     * @throws IOException               ioexception
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public ObjectWriteResponse uploadFile(String bucketName, String objectName, String fileName)
            throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.uploadObject(
                UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
    }
    
    /**
     * 通过流上传文件
     *
     * @param bucketName  存储桶
     * @param objectName  文件对象
     * @param inputStream 文件流
     * @return {@link ObjectWriteResponse}
     * @throws IOException               ioexception
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    
    public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream)
            throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
                .stream(inputStream, inputStream.available(), -1).build());
    }
    
    /**
     * 创建目录
     *
     * @param bucketName 存储桶
     * @param objectName 目录路径
     * @return {@link ObjectWriteResponse}
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public ObjectWriteResponse createDir(String bucketName, String objectName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
                .stream(new ByteArrayInputStream(new byte[] {}), 0, -1).build());
    }
    
    /**
     * 获取文件状态信息
     *
     * @param bucketName 存储桶
     * @param objectName 文件名称
     * @return {@link String}
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public String getFileStatusInfo(String bucketName, String objectName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build())
                .toString();
    }
    
    /**
     * 复制文件
     *
     * @param bucketName    存储桶
     * @param objectName    文件名
     * @param srcBucketName 目标存储桶
     * @param srcObjectName 目标文件名
     * @return {@link ObjectWriteResponse}
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    
    public ObjectWriteResponse copyFile(String bucketName, String objectName, String srcBucketName,
            String srcObjectName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        return minioClient.copyObject(
                CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build())
                        .bucket(srcBucketName).object(srcObjectName).build());
    }
    
    /**
     * 删除文件
     *
     * @param bucketName 存储桶
     * @param objectName 文件名称
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public void removeFile(String bucketName, String objectName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }
    
    /**
     * 批量删除文件
     *
     * @param bucketName 存储桶
     * @param keys       需要删除的文件列表
     */
    public void batchRemoveFiles(String bucketName, List<String> keys) {
        
        List<DeleteObject> objects = new LinkedList<>();
        keys.forEach(s -> {
            objects.add(new DeleteObject(s));
            try {
                removeFile(bucketName, s);
            } catch (Exception e) {
                log.error("[Minio工具类]>>>> 批量删除文件,异常:", e);
            }
        });
    }
    
    /**
     * 获取文件外链
     *
     * @param bucketName 存储桶
     * @param objectName 文件名
     * @param expires    过期时间 <=7 秒 (外链有效时间(单位:秒))
     * @return url
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName)
                .object(objectName).build();
        return minioClient.getPresignedObjectUrl(args);
    }
    
    /**
     * 获得文件外链
     *
     * @param bucketName 桶名称
     * @param objectName 对象名称
     * @return url
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws ErrorResponseException    错误响应异常
     * @throws IOException               ioexception
     * @throws NoSuchAlgorithmException  没有这样算法例外
     * @throws InvalidKeyException       无效密钥异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML 解析器异常
     * @throws InternalException         内部异常
     */
    public String getPresignedObjectUrl(String bucketName, String objectName)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().bucket(minioConfig.getBucketName())
                .object(objectName).method(Method.GET).build();
        
        return minioClient.getPresignedObjectUrl(args);
    }
    
    /**
     * 将URLDecoder编码转成UTF8
     *
     * @param str 要转换的字符串
     * @return {@link String}
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    public String getUtf8ByUrlDecoder(String str) throws UnsupportedEncodingException {
        
        String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
        return URLDecoder.decode(url, "UTF-8");
    }
    
    
    /**
     * 文件是否存在
     *
     * @param fileName   文件名称
     * @param bucketName 存储桶名称
     * @return boolean
     */
    public boolean fileIsExists(String bucketName, String fileName) {
        
        boolean exist = true;
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            log.error("判断文件是否存在出现异常{}:", e.getMessage(), e);
            exist = false;
        }
        return exist;
        
    }
}

4. 使用

没必要演示,直接调用工具类使用即可

giteeopen in new window

github

    /**
     * 下载文件
     *
     * @param fileName 文件名
     * @param response 响应
     */
    @GetMapping("/download/{fileName}")
    public void downloadFile(@PathVariable("fileName") String fileName, HttpServletResponse response) {
        try {
            InputStream fileInputStream = minioUtils.getObject(minioConfig.getBucketName(), fileName);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(fileInputStream, response.getOutputStream());
        } catch (Exception e) {
            log.error("下载失败{}:", e.getMessage(), e);
        }
    }
上次编辑于: