The Minio Java framework for object storage spring cloud encapsulates the Minio SDK as an http interface

Keywords: Java Big Data http

preface

Due to the needs of the project, binary files such as audio and images need to be stored. These files cannot be stored in the database. HBase has been used for audio storage before. However, HBase's api is too complex to use

There is also fastdfs for file storage, but the installation and configuration is very complex. Later, I found minio in my work. This software is easy to use. Next, I will introduce the process of encapsulating the interface

The framework I use in this article is spring cloud. You need to understand spring cloud before you can understand the code

Introduction to mioIO

Build high-performance cloud native data
Machine learning, big data analysis, mass storage infrastructure
MinIO supports a variety of application data workloads
In China: more than 9000 enterprises such as Alibaba, Tencent, Baidu, China Unicom, Huawei and China Mobile are also using MinIO products

Build test service

Download the server at the following address
http://www.minio.org.cn/
I downloaded the win version
Start with the following command

minio.exe server D:\usr\local

The startup interface is as follows:

minio's object storage service has been started at 9000

JAVA code encapsulates Minio API

Introduce Java SDK and add the following dependencies in the pom file

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

Here, I only encapsulate two interfaces, a download interface and an upload file interface, and create the minio configuration class MinioConfig

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

    @ApiModelProperty("endPoint It's a URL,Domain name, IPv4 perhaps IPv6 address")
    private String endpoint;

    @ApiModelProperty("Port number")
    private int port;

    @ApiModelProperty("accessKey Similar to user ID,Unique identification account")
    private String accessKey;

    @ApiModelProperty("secretKey Is the account password")
    private String secretKey;

    @ApiModelProperty("If it is true,Use https instead of http,The default value is true")
    private Boolean secure;

    @ApiModelProperty("Audio storage bucket")
    private String voiceBucketName;

    @ApiModelProperty("url prefix")
    private String urlPrefix;

    @Bean
    public MinioClient getMinioClient() throws InvalidEndpointException, InvalidPortException {
        MinioClient minioClient = new MinioClient(endpoint, port, accessKey, secretKey, secure);
        return minioClient;
    }
}

bootstrap.properties is configured as follows:

# minio configuration
minio.endpoint=localhost
minio.port=9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.secure=false
minio.voiceBucketName=voice-file
minio.urlPrefix=www.ooo.cn/pro

Write a service interface

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;

public interface MinioService {


    /**
     * Determine whether the bucket exists
     *
     * @param bucketName
     * @return
     */
    boolean bucketExists(String bucketName);

    /**
     * Create bucket
     *
     * @param bucketName
     */
    void makeBucket(String bucketName);

    /**
     * File upload
     *
     * @param multipartFile
     */
    String uploadFile(MultipartFile multipartFile);

    /**
     * Delete file
     * @param objectName
     */
    boolean deleteFile(String objectName);

    /**
     * Download File
     * @param fileName
     * @param originalName
     * @param response
     */
    void downloadFile(String originalName, String fileName, HttpServletResponse response);

    /**
     * Get file path
     * @param objectName
     * @return
     */
    String getFileUrl(String objectName);


    /**
     * Get file stream
     * @param objectName
     * @return
     */
    InputStream getInputStreamByObjectName(String objectName);


}

Writing interface implementation classes

mport com.ifly.assi.config.MinioConfig;
import com.ifly.assi.service.impl.MinioService;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.ErrorResponseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


@Service
@Slf4j
public class MinioServiceImpl implements MinioService {

    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private MinioClient minioClient;

    /**
     * Determine whether the bucket exists
     * @param bucketName
     * @return
     */
    @Override
    public boolean bucketExists(String bucketName) {
        boolean flag = false;
        try {
            flag = minioClient.bucketExists(bucketName);
            if (flag) {
                return true;
            }
        } catch (Exception e){
            log.error("query bucket = {}Is there an error", bucketName, e);
        }

        return false;
    }

    /**
     * Create bucket
     * @param bucketName
     */
    @Override
    public void makeBucket(String bucketName) {
        boolean flag = bucketExists(bucketName);
        try {
            if (!flag) {
                minioClient.makeBucket(bucketName);
            }
        } catch (Exception e){
            log.error("establish bucket = {}error", bucketName, e);
        }

    }

    /**
     * Upload file
     * @param multipartFile
     * @return File path
     */
    @Override
    public String uploadFile(MultipartFile multipartFile) {
        // Generate the file directory by date and regenerate the file name with uuid
        String fileName = multipartFile.getOriginalFilename();
        String objName = getObjectNameByFileName(fileName);
        PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);
        putObjectOptions.setContentType(multipartFile.getContentType());
        try {
            minioClient.putObject(minioConfig.getVoiceBucketName(), objName, multipartFile.getInputStream(), putObjectOptions);
        } catch (Exception e){
            log.error("Upload file{}error", fileName, e);
        }
        return objName;
    }

    private String getObjectNameByFileName(String fileName) {
        if (StringUtils.isBlank(fileName)) {
            return "";
        }
        String dateFormat = new SimpleDateFormat("yyyy/MM/dd/").format(new Date());
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String objName = dateFormat + uuid + fileType;
        return objName;
    }

    /**
     * Delete file
     * @param objectName
     */
    @Override
    public boolean deleteFile(String objectName) {
        boolean flag = bucketExists(minioConfig.getVoiceBucketName());
        if (flag) {
            try {
                minioClient.removeObject(minioConfig.getVoiceBucketName(), objectName);
            }catch (Exception e){
                log.error("Delete file objectName = {},error", objectName, e);
            }
            return true;
        }
        return false;
    }

    /**
     * Download File
     * @param objectName Store object name
     * @param fileName The file name displayed when downloading
     * @param response
     */
    @Override
    public void downloadFile(String objectName, String fileName, HttpServletResponse response) {
        try {
            InputStream file = minioClient.getObject(minioConfig.getVoiceBucketName(), objectName);
            String filename = new String(fileName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = file.read(buffer)) > 0) {
                servletOutputStream.write(buffer, 0, len);
            }
            servletOutputStream.flush();
            file.close();
            servletOutputStream.close();
        } catch (ErrorResponseException e) {
            log.error("Download File{}error", fileName, e);
        } catch (Exception e) {
            log.error("Download File{}error", fileName, e);
        }
    }

    /**
     * Get file path
     * @param objectName
     * @return
     */
    @Override
    public String getFileUrl(String objectName) {
        boolean flag = bucketExists(minioConfig.getVoiceBucketName());
        String url = "";
        if (flag) {
            try {
                url = minioClient.getObjectUrl(minioConfig.getVoiceBucketName(), objectName);
            } catch (Exception e){
                log.error("get files{}Path error", objectName, e);
            }
        }
        return url;
    }

    @Override
    public InputStream getInputStreamByObjectName(String objectName) {
        InputStream inputStream = null;
        try {
             inputStream = minioClient.getObject(minioConfig.getVoiceBucketName(), objectName);
        } catch (Exception e) {
            log.error("Error getting file stream", e);
        }
        return inputStream;
    }

}

New MinioController

import com.ifly.assi.dto.DataResult;
import com.ifly.assi.service.impl.MinioService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@RequestMapping("/minio")
@RestController
@Api(tags = "Minio File service")
@Slf4j
public class MinioController {

    @Autowired
    private MinioService minioService;

    @Autowired
    private HttpServletResponse response;

    @ApiOperation(value = "Upload file")
    @PostMapping("/uploadFile")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "MultipartFile", name = "file", value = "Uploaded files", required = true)
    })
    public DataResult uploadFile(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        try {
            String objectName = minioService.uploadFile(file);
            return new DataResult(objectName);
        } catch (Exception e) {
            log.error("Upload file fileName = {}error", fileName, e);
            return DataResult.fail("Upload failed");
        }
    }

    @GetMapping("/downloadFile")
    @ApiOperation(value = "Download File")
    public void downloadFile(String objectName, String fileName) {
        minioService.downloadFile(objectName, fileName, response);
    }
}

Because swagger is used in my project, there are some swagger annotations on the interface, such as @ ApiOperation, @ Api, which can be deleted if you test it yourself

At this point, the encapsulation of Minio SDK has been completed, and you can start testing

result

Upload file interface

Download the interface without screenshots. If you like, please pay attention

Posted by Canadian on Sun, 24 Oct 2021 13:04:21 -0700