Java implementa la carga, descarga y eliminación de archivos minio y admite el acceso https

MinIO es un sistema de almacenamiento de objetos distribuido de alto rendimiento. Minio es un servicio de almacenamiento de objetos escrito en lenguaje Go. Es adecuado para almacenar datos no estructurados de gran capacidad, como imágenes, audio, video, datos de respaldo, etc. Almacenamiento de objetos tradicional Excelente rendimiento en casos de uso como almacenamiento secundario, recuperación ante desastres y archivado.

1. Configuración

Importar paquete de dependencia minio

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.0.3</version>
        </dependency>

archivo de configuración application.yml

minio:
  #注意此处是https,由于后续讨论协议问题因此提前修改,不需要的可自行修改为http
  endpoint: https://xxx.xxx.xx:9002 
  accesskey: minioadmin  #你的服务账号
  secretkey: minioadmin  #你的服务密码

Configurar el archivo MinioInfo

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

    private String endpoint;

    private String accesskey;

    private String secretkey;
}

Configurar el archivo MinioConfig

@Configuration
@EnableConfigurationProperties(MinioInfo.class)
public class MinioConfig {

    @Autowired
    private MinioInfo minioInfo;

    /**
     * 获取 MinioClient
     */
    @Bean
    public MinioClient minioClient() throws NoSuchAlgorithmException, KeyManagementException {
        return MinioClient.builder().endpoint(minioInfo.getEndpoint())
                .credentials(minioInfo.getAccesskey(),minioInfo.getSecretkey())
                .build();
   }
}

2. Cargar, descargar y eliminar archivos

Clase MinioUtils

import io.minio.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author: MM
 * @date: 2023-03-09 10:09
 */
@Slf4j
@Component
public class MinioUtils {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioInfo minioInfo;


    /**
     * 上传文件
     * @param file
     * @param bucketName
     * @return
     * @throws Exception
     */
    public String uploadFile(MultipartFile file,String bucketName){
        if (null==file || 0 == file.getSize()){
            log.error("msg","上传文件不能为空");
            return null;
        }
        try {
            //判断是否存在
            createBucket(bucketName);
            //原文件名
            String originalFilename=file.getOriginalFilename();
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucketName).object(originalFilename).stream(
                            file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
            return minioInfo.getEndpoint()+"/"+bucketName+"/"+originalFilename;
        }catch (Exception e){
            log.error("上传失败:{}",e.getMessage());
        }
        log.error("msg","上传失败");
        return null;
    }

   /**
     * 通过字节流上传
     * @param imageFullPath
     * @param bucketName
     * @param imageData
     * @return
     */
    public String uploadImage(String imageFullPath,
                              String bucketName,
                              byte[] imageData){
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(imageData);
        try {
            //判断是否存在
            createBucket(bucketName);
            minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(imageFullPath)
                    .stream(byteArrayInputStream,byteArrayInputStream.available(),-1)
                    .contentType(".jpg")
                    .build());
            return minioInfo.getEndpoint()+"/"+bucketName+"/"+imageFullPath;
        }catch (Exception e){
            log.error("上传失败:{}",e.getMessage());
        }
        log.error("msg","上传失败");
        return null;
    }

    /**
     * 删除文件
     * @param bucketName
     * @param fileName
     * @return
     */
    public int removeFile(String bucketName,String fileName){
        try {
            //判断桶是否存在
            boolean res=minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (res) {
                //删除文件
                minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName)
                        .object(fileName).build());
            }
        } catch (Exception e) {
            System.out.println("删除文件失败");
            e.printStackTrace();
            return 1;
        }
        System.out.println("删除文件成功");
        return 0;
    }

/**
     * 下载文件
     * @param fileName
     * @param bucketName
     * @param response
     */
    public void fileDownload(String fileName,
                             String bucketName,
                             HttpServletResponse response) {

        InputStream inputStream   = null;
        OutputStream outputStream = null;
        try {
            if (StringUtils.isBlank(fileName)) {
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                String data = "文件下载失败";
                OutputStream ps = response.getOutputStream();
                ps.write(data.getBytes("UTF-8"));
                return;
            }

            outputStream = response.getOutputStream();
            // 获取文件对象
            inputStream =minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            byte buf[] = new byte[1024];
            int length = 0;
            response.reset();
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(fileName.substring(fileName.lastIndexOf("/") + 1), "UTF-8"));
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            // 输出文件
            while ((length = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, length);
            }
            System.out.println("下载成功");
            inputStream.close();
        } catch (Throwable ex) {
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            String data = "文件下载失败";
            try {
                OutputStream ps = response.getOutputStream();
                ps.write(data.getBytes("UTF-8"));
            }catch (IOException e){
                e.printStackTrace();
            }
        } finally {
            try {
                outputStream.close();
                if (inputStream != null) {
                    inputStream.close();
                }}catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    @SneakyThrows
    public void createBucket(String bucketName) {
        //如果不存在就创建
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }
}

A continuación, simplemente cree un controlador y úselo.

subir

/**
     * 上传文件
     * @param file
     * @return
     */
@PostMapping(value = "/v1/minio/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public JSONObject uploadByMinio(@RequestParam(name = "file")MultipartFile file) {
        JSONObject jso = new JSONObject();
        //返回存储路径
        String path = minioUtils.uploadFile(file, "musicearphone");
        jso.put("code", 2000);
        jso.put("data", path);
        return jso;
    }

descargar

/**
     * 下载文件 根据文件名
     * @param fileName
     * @param response
     */
    @GetMapping("/v1/get/download")
    public void download(@RequestParam(name = "fileName") String fileName,
                         HttpServletResponse response){
        try {
            minioUtils.fileDownload(fileName,"musicearphone",response);
        }catch (Exception e){
            e.printStackTrace();

        }
    }

borrar

/**
     * 通过文件名删除文件
     * @param fileName
     * @return
     */
@PostMapping("/v1/minio/delete")
    @ResponseBody
    public JSONObject deleteByName(String fileName){
        JSONObject jso = new JSONObject();
        int res = minioUtils.removeFile("musicearphone", fileName);
        if (res!=0){
            jso.put("code",5000);
            jso.put("msg","删除失败");
        }
        jso.put("code",2000);
        jso.put("msg","删除成功");
        return jso;
    }

3. Admite acceso https

Debido al proyecto de la empresa, el método de acceso al proyecto es https. El servidor minio es http cuando se integra al principio. En el artículo anterior, minio activó https.

Enlace del artículo: https://blog.csdn.net/weixin_53799443/article/details/129335521

Pero en el proceso de utilizar el servicio minio https, descubrí que se informó el error de carga del archivo.

El siguiente error ha ocurrido

sun.security.validator.ValidatorException: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target

causas del problema

La aplicación de origen no confía en el certificado de la aplicación de destino porque el certificado o la cadena de certificados no se encuentra en el almacén de confianza JVM de la aplicación de origen (en pocas palabras, el servicio minio no confía en la emisión del certificado)

Solución

Cancele la autenticación SSL mediante código Java y actualice el archivo MinioConfig

import io.minio.MinioClient;

import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

/**
 * @author: MM
 * @date: 2023-03-09 10:05
 */
@Configuration
@EnableConfigurationProperties(MinioInfo.class)
public class MinioConfig {

    @Autowired
    private MinioInfo minioInfo;

    /**
     * 获取 MinioClient
     * 取消ssl认证
     */
    @Bean
    public MinioClient minioClient() throws NoSuchAlgorithmException, KeyManagementException {
//        return MinioClient.builder().endpoint(minioInfo.getEndpoint())
//                .credentials(minioInfo.getAccesskey(),minioInfo.getSecretkey())
//                .build();
        //取消ssl认证
        final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
                    }
                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
                    }
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };

        X509TrustManager x509TrustManager = (X509TrustManager) trustAllCerts[0];
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new SecureRandom());
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory,x509TrustManager);

        builder.hostnameVerifier((s, sslSession) -> true);
        OkHttpClient okHttpClient = builder.build();

        return MinioClient.builder().endpoint(minioInfo.getEndpoint()).httpClient(okHttpClient).region("eu-west-1").credentials(minioInfo.getAccesskey()
                , minioInfo.getSecretkey()).build();
    }

}

Supongo que te gusta

Origin blog.csdn.net/weixin_53799443/article/details/129442953
Recomendado
Clasificación