minio部署及接口封装升级优化

本文介绍MinIO单机部署流程与多级目录创建技巧,解析如何通过修改上传接口实现多级目录支持,并分享了预览图片数据的方法及部署过程中可能遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

minio部署及接口封装升级优化


一、单机部署步骤

与集群部署不同点:

  1. 启动脚本 nohup ./minio server /data/minio/ &
  2. 单机服务器不同于集群部署,需要最4个存储,单存储就可以

二、多级目录创建

  1. minio桶(bucketName)是一个全局唯一的,只作为一级节点,不能为多级节点
  2. 数据对象(objectName)是桶里的存储对象,多级目录可以从改参数入手
  3. 参考 springboot 集成 Minio 文件服务器博文 修改上传接口,重点在于拆分bucket参数构建objectName。
    eg:
    入参buckt :data/template/plan file:xxxx.jpg
    构建: bucket:data objectName:/template/plan/xxxx.jpg
    private final String splitChar = "/";

    @Value("${minio-bucketName}")
    private String bucketName;
    
	@Override
    public AttachmentOutDTO upload(MultipartFile file, String bucket) {
        final String fileName = file.getOriginalFilename();
        AttachmentOutDTO dto = new AttachmentOutDTO();
		//一些校验
        BizPreconditions.checkArgumentNoStack(file.getSize() < MAX_UPLOAD_SIZE,
                "超出附件大小限制" + (MAX_UPLOAD_SIZE / 1024) / 1024 + "M");
        BizPreconditions.checkArgumentNoStack(!file.isEmpty(), "上传附件不能为空!");
        BizPreconditions.checkArgumentNoStack(fileName.length() < MinioConstants.FILENAMELENGTH,
                "附件名称长度不能超过100!,此附件名长度为: " + fileName.length());
        //不支持向模板目录上传文件
        BizPreconditions.checkArgumentNoStack(!MinioConstants.TEMPLATE.equals(bucket), MinioConstants.TEMPLATE + "为保留桶,请更换桶名称!");
        // 得到文件流
        final InputStream is;
        try {
            is = file.getInputStream();
            String attachId = UUIDUtil.uuid();
            String fileHz = fileName.substring(fileName.lastIndexOf("."));
            String newFileName = attachId + fileHz;
            //前端传递多级bucket时对bucket拆分
            if (bucket != null && bucketName.contains(splitChar)) {
                newFileName = bucket.substring(bucket.indexOf(splitChar) + 1) + splitChar + newFileName;
                bucket = bucket.split(splitChar)[0];
            }
            //前端不传递bucket时取配置中的bucketName
            else if (bucketName.contains(splitChar)) {
                newFileName = bucketName.substring(bucketName.indexOf(splitChar) + 1) + splitChar + newFileName;
                bucket = bucketName.split(splitChar)[0];
            }

            bucket = minioTemplate.putObject(bucket, newFileName, file);
            String objectUrl = minioTemplate.getObjectUrl(bucket, newFileName);
            // 关闭输入流
            is.close();
            dto.setName(fileName);
            dto.setUrl(objectUrl);
            dto.setFileId(attachId);
            //中间路径
            String midDirPath = bucket + File.separator;
            //path是一个不完整路径,缺少路径根目录
            String midDirPathAndFileName = midDirPath + newFileName;
            //附件信息入库
            attachmentService.uploadAttachment(attachId, midDirPathAndFileName, "userId", fileName);
            return dto;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("文件上传失败");
        }
    }

三、url图片数据预览

minio java封装后保存了附件信息,主要包括id,path、oldname,path是minio保存路径,添加minio外网代理地址后可获取到上传图片访问地址,但minio默认并不支持直接预览,它会将xxxx.jpg视为一个目录而不是图片。
在这里插入图片描述

客户端可以设置所在桶Policy为只读即可。
在这里插入图片描述
代码端修改MinioTemplate:调用创建桶时会自动将该桶设置为只读。

    /**
     * 创建bucket
     * setBucketPolicy 设置权限才可以预览
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void createBucket(String bucketName) {
        if (!bucketExists(bucketName)) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            StringBuilder builder = new StringBuilder();
            builder.append("{\n");
            builder.append("    \"Statement\": [\n");
            builder.append("        {\n");
            builder.append("            \"Action\": [\n");
            builder.append("                \"s3:GetBucketLocation\",\n");
            builder.append("                \"s3:ListBucket\"\n");
            builder.append("            ],\n");
            builder.append("            \"Effect\": \"Allow\",\n");
            builder.append("            \"Principal\": \"*\",\n");
            builder.append("            \"Resource\": \"arn:aws:s3:::my-bucketname\"\n");
            builder.append("        },\n");
            builder.append("        {\n");
            builder.append("            \"Action\": \"s3:GetObject\",\n");
            builder.append("            \"Effect\": \"Allow\",\n");
            builder.append("            \"Principal\": \"*\",\n");
            builder.append("            \"Resource\": \"arn:aws:s3:::my-bucketname/*.*\"\n");
            builder.append("        }\n");
            builder.append("    ],\n");
            builder.append("    \"Version\": \"2012-10-17\"\n");
            builder.append("}\n");
            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(builder.toString().replace("my-bucketname",bucketName)).build());
        }
    }

四、遇到的问题

ErrorResponse(code = AccessDenied, message = Access denied, bucketName = data…
minio服务器和当前应用服务器分离部署时,需要保证两个服务器时间相差不大

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr-Wanter

感谢大佬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值