CDN到期不想续费?!MINIO救个场!

一、安装MINIO

下载

wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230413030807.0.0.x86_64.rpm -O minio.rpm

安装

yum install minio.rpm

二、启动 MinIO 服务器

  • 创建启动实例目录
mkdir ~/minio
  • 启动 MInIO实例
minio server ~/minio --console-address :9090

启动成功界面截图如下:

CDN到期不想续费?!MINIO救个场!_第1张图片

启动成功后可以看到 MinIO 版本。 

 三、创建凭据密钥

  • 登录:http://localhost:9090

账号:minioadmin

密码:minioadmin

  • Create Bucket

创建桶示例截图如下:

CDN到期不想续费?!MINIO救个场!_第2张图片

  • 创建租户

创建租户示例截图如下:

CDN到期不想续费?!MINIO救个场!_第3张图片

  • 创建凭据密钥

首先点击用户,如下:

CDN到期不想续费?!MINIO救个场!_第4张图片

 接下来进入如下界面后,点击【Create Access Key】

CDN到期不想续费?!MINIO救个场!_第5张图片

 接下来进入如下界面后点击【Create】

CDN到期不想续费?!MINIO救个场!_第6张图片

 弹窗后,点击【Download for import】下载,如下 截图

CDN到期不想续费?!MINIO救个场!_第7张图片

下载后内容如下:

{"url":"http://127.0.0.1:9000","accessKey":"FZULfNYYF3LtrnOx","secretKey":"k3DPt92mF5D6GhfVgiQhOlDoNdXNBcng","api":"s3v4","path":"auto"}

 注意:url和登录时的端口不一样哦,接下来整合到Spring Boot中时要用到!

四、Spring Boot 整合 Minio

  • 添加依赖
        
            io.minio
            minio
            8.5.2
        
  • 在 application.properties 中添加 minio 密钥,如下:
################################## minio 配置 ##################################
spring.minio.url=http://127.0.0.1:9000
spring.minio.access-key=FZULfNYYF3LtrnOx
spring.minio.secret-key=k3DPt92mF5D6GhfVgiQhOlDoNdXNBcng
spring.minio.bucket-name=song
  • 创建读取配置类
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * minio配置读取
 *
 * @author songjianyong
 */
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
@Data
public class MinioConfiguration {
    private String accessKey;
    private String secretKey;
    private String url;
    private String bucketName;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(url)
                .credentials(accessKey, secretKey)
                .build();
    }
}
  • 创建minio 服务接口及实现类

接口代码如下

import io.minio.http.Method;
import org.springframework.web.multipart.MultipartFile;

import java.time.ZonedDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * minio 服务接口
 *
 * @author songjianyong
 */
public interface IMinioService {
    /**
     * 获取上传临时签名
     *
     * @param fileName 文件名称
     * @param time     时间
     * @return {@link Map}
     */
    Map getPolicy(String fileName, ZonedDateTime time);

    /**
     * 获取上传文件的url
     *
     * @param objectName 对象名称
     * @param method     方法
     * @param time       时间
     * @param timeUnit   时间单位
     * @return {@link String}
     */
    String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit);

    /**
     * 上传文件
     *
     * @param file     文件
     * @param fileName 文件名称
     */
    void upload(MultipartFile file, String fileName);

    /**
     * 根据filename获取文件访问地址
     *
     * @param objectName 对象名称
     * @param time       时间
     * @param timeUnit   时间单位
     * @return {@link String}
     */
    String getUrl(String objectName, int time, TimeUnit timeUnit);
}

接口实现如下

import com.coocaa.spider.imdb.config.MinioConfiguration;
import com.coocaa.spider.imdb.service.IMinioService;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PostPolicy;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * minio服务
 *
 * @author songjianyong
 * @date 2023/04/18
 */
@Slf4j
@Service
public class MinioServiceImpl implements IMinioService {
    @Resource
    private MinioClient minioClient;

    @Resource
    private MinioConfiguration minioConfiguration;


    @Override
    public Map getPolicy(String fileName, ZonedDateTime time) {
        PostPolicy postPolicy = new PostPolicy(minioConfiguration.getBucketName(), time);
        postPolicy.addEqualsCondition("key", fileName);
        try {
            Map postFormData = minioClient.getPresignedPostFormData(postPolicy);
            HashMap policyMap = new HashMap<>(8);
            postFormData.forEach((k, v) -> {
                policyMap.put(k.replaceAll("-", ""), v);
            });
            policyMap.put("host", minioConfiguration.getUrl() + "/" + minioConfiguration.getBucketName());
            return policyMap;
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(method)
                    .bucket(minioConfiguration.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException | ServerException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }


    @Override
    public void upload(MultipartFile file, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try(InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfiguration.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public String getUrl(String objectName, int time, TimeUnit timeUnit) {
        String url = null;
        try {
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioConfiguration.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException | ServerException e) {
            log.error(e.getMessage(), e);
        }
        return url;
    }
}
  •  创建上传文件Controller类
import com.coocaa.spider.imdb.service.IMinioService;
import com.coocaa.spider.imdb.vo.ResponseVO;
import io.minio.http.Method;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 上传文件控制器
 *
 * @author songjianyong
 * @date 2023/04/18
 */
@RestController
@RequestMapping("/minio")
@Validated
public class UploadController {

    @Resource
    private IMinioService minioService;

    @PostMapping("/upload")
    public ResponseVO upload(@RequestParam("file") MultipartFile file, @RequestParam("fileName") String fileName) {
        minioService.upload(file, fileName);
        String url = minioService.getUrl(fileName, 7, TimeUnit.DAYS);
        return ResponseVO.buildSuccessResult(url);
    }

    @GetMapping("/policy")
    public ResponseVO> policy(@RequestParam("fileName") String fileName) {
        Map policy = minioService.getPolicy(fileName, ZonedDateTime.now().plusMinutes(10));
        return ResponseVO.buildSuccessResult(policy);
    }

    @GetMapping("/uploadUrl")
    public ResponseVO uploadUrl(@RequestParam("fileName") String fileName) {
        String url = minioService.getPolicyUrl(fileName, Method.PUT, 2, TimeUnit.MINUTES);
        return ResponseVO.buildSuccessResult(url);
    }

    @GetMapping("/url")
    public ResponseVO getUrl(@RequestParam("fileName") String fileName) {
        String url = minioService.getUrl(fileName, 7, TimeUnit.DAYS);
        return ResponseVO.buildSuccessResult(url);
    }
}

启动服务后使用 Postman 上传成功示例截图如下:

CDN到期不想续费?!MINIO救个场!_第8张图片

你可能感兴趣的:(IO,spring,网络编程,minio,spring,boot)