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