¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.utils.file; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.IdWorker; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import com.ruoyi.common.core.domain.MinioResult; |
| | | import com.ruoyi.common.exception.UtilException; |
| | | import com.ruoyi.common.exception.file.InvalidExtensionException; |
| | | import io.minio.*; |
| | | import io.minio.http.Method; |
| | | import io.minio.messages.DeleteError; |
| | | import io.minio.messages.DeleteObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.FastByteArrayOutputStream; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.ServletOutputStream; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Component |
| | | public class MinioUtils { |
| | | @Autowired |
| | | private MinioClient minioClient; |
| | | |
| | | @Value("${minio.preview-expiry}") |
| | | private Integer previewExpiry; |
| | | |
| | | /** |
| | | * 夿å卿¡¶æ¯å¦åå¨ï¼ä¸åå¨åå建 |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | */ |
| | | public void existBucket(String bucketName) { |
| | | try { |
| | | boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); |
| | | if (!exists) { |
| | | minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å建å卿¡¶ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @return æ¯å¦å建æå |
| | | */ |
| | | public Boolean makeBucket(String bucketName) { |
| | | try { |
| | | minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * å é¤å卿¡¶ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @return æ¯å¦å 餿å |
| | | */ |
| | | public Boolean removeBucket(String bucketName) { |
| | | try { |
| | | minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * å¤æå¯¹è±¡æ¯å¦åå¨ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param originalFileName MinIOä¸åå¨å¯¹è±¡å
¨è·¯å¾ |
| | | * @return 对象æ¯å¦åå¨ |
| | | */ |
| | | public boolean existObject(String bucketName, String originalFileName) { |
| | | try { |
| | | minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(originalFileName).build()); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * æä»¶ä¸ä¼ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param file æä»¶ |
| | | * @return æ¡¶ä¸ä½ç½® |
| | | */ |
| | | public MinioResult upload(String bucketName, MultipartFile file, Boolean isPreviewExpiry) throws InvalidExtensionException { |
| | | MultipartFile[] fileArr = {file}; |
| | | List<MinioResult> fileNames = upload(bucketName, fileArr, isPreviewExpiry); |
| | | return fileNames.isEmpty() ? null : fileNames.get(0); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ æä»¶ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param fileList æä»¶å表 |
| | | * @return æ¡¶ä¸ä½ç½®å表 |
| | | */ |
| | | public List<MinioResult> upload(String bucketName, List<MultipartFile> fileList, Boolean isPreviewExpiry) throws InvalidExtensionException { |
| | | MultipartFile[] fileArr = fileList.toArray(new MultipartFile[0]); |
| | | return upload(bucketName, fileArr, isPreviewExpiry); |
| | | } |
| | | |
| | | /** |
| | | * description: ä¸ä¼ æä»¶ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param fileArr æä»¶å表 |
| | | * @return æ¡¶ä¸ä½ç½®å表 |
| | | */ |
| | | public List<MinioResult> upload(String bucketName, MultipartFile[] fileArr, Boolean isPreviewExpiry) throws InvalidExtensionException { |
| | | for (MultipartFile file : fileArr) { |
| | | FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); |
| | | } |
| | | // ä¿è¯æ¡¶ä¸å®åå¨ |
| | | existBucket(bucketName); |
| | | // æ§è¡æ£å¸¸æä½ |
| | | List<MinioResult> bucketFileNames = new ArrayList<>(fileArr.length); |
| | | for (MultipartFile file : fileArr) { |
| | | // è·ååå§æä»¶åç§° |
| | | String originalFileName = file.getOriginalFilename(); |
| | | // è·åå½åæ¥æï¼æ ¼å¼ä¾å¦ï¼2020-11 |
| | | String datePath = new SimpleDateFormat("yyyy-MM").format(new Date()); |
| | | // æä»¶åç§° |
| | | String uuid = IdWorker.get32UUID(); |
| | | // è·åæä»¶åç¼ |
| | | String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")); |
| | | String bucketFilePath = datePath + "/" + uuid + suffix; |
| | | |
| | | // æ¨éæä»¶å°MinIO |
| | | try (InputStream in = file.getInputStream()) { |
| | | minioClient.putObject(PutObjectArgs.builder() |
| | | .bucket(bucketName) |
| | | .object(bucketFilePath) |
| | | .stream(in, in.available(), -1) |
| | | .contentType(file.getContentType()) |
| | | .build() |
| | | ); |
| | | } catch (Exception e) { |
| | | throw new UtilException("MinioUtilsï¼ä¸ä¼ æä»¶å·¥å
·ç±»å¼å¸¸"); |
| | | } |
| | | MinioResult minioResult = new MinioResult(); |
| | | minioResult.setBucketFileName(bucketFilePath); |
| | | // è¿åæ°¸ä¹
é¢è§å°å |
| | | if (isPreviewExpiry) { |
| | | String previewUrl = getPreviewUrl(bucketFilePath, bucketName, isPreviewExpiry); |
| | | minioResult.setPreviewExpiry(previewUrl); |
| | | } |
| | | minioResult.setOriginalName(originalFileName); |
| | | bucketFileNames.add(minioResult); |
| | | } |
| | | return bucketFileNames; |
| | | } |
| | | |
| | | /** |
| | | * æä»¶ä¸è½½ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param bucketFileName æ¡¶ä¸æä»¶åç§° |
| | | * @param originalFileName åå§æä»¶åç§° |
| | | * @param response response对象 |
| | | */ |
| | | public void download(String bucketName, String bucketFileName, String originalFileName, HttpServletResponse response) { |
| | | GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(bucketFileName).build(); |
| | | try (GetObjectResponse objResponse = minioClient.getObject(objectArgs)) { |
| | | byte[] buf = new byte[1024]; |
| | | int len; |
| | | try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) { |
| | | while ((len = objResponse.read(buf)) != -1) { |
| | | os.write(buf, 0, len); |
| | | } |
| | | os.flush(); |
| | | byte[] bytes = os.toByteArray(); |
| | | response.setCharacterEncoding("utf-8"); |
| | | //设置强å¶ä¸è½½ä¸æå¼ |
| | | response.setContentType("application/force-download"); |
| | | // 设置éä»¶åç§°ç¼ç |
| | | originalFileName = new String(originalFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); |
| | | // 设置éä»¶åç§° |
| | | response.addHeader("Content-Disposition", "attachment;fileName=" + originalFileName); |
| | | // åå
¥æä»¶ |
| | | try (ServletOutputStream stream = response.getOutputStream()) { |
| | | stream.write(bytes); |
| | | stream.flush(); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new UtilException("MinioUtilsï¼ä¸ä¼ æä»¶å·¥å
·ç±»å¼å¸¸"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åå·²ä¸ä¼ 对象çæä»¶æµï¼å端å 为ä¸å¡éè¦è·åæä»¶æµå¯ä»¥è°ç¨è¯¥æ¹æ³ï¼ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param bucketFileName æ¡¶ä¸æä»¶åç§° |
| | | * @return æä»¶æµ |
| | | */ |
| | | public InputStream getFileStream(String bucketName, String bucketFileName) throws Exception { |
| | | GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(bucketFileName).build(); |
| | | return minioClient.getObject(objectArgs); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤æä»¶å¯¹è±¡ç»æ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param bucketFileName æ¡¶ä¸æä»¶åç§° |
| | | * @return å é¤ç»æ |
| | | */ |
| | | public DeleteError removeObjectsResult(String bucketName, String bucketFileName) { |
| | | List<DeleteError> results = removeObjectsResult(bucketName, Collections.singletonList(bucketFileName)); |
| | | return !results.isEmpty() ? results.get(0) : null; |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤æä»¶å¯¹è±¡ç»æ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param bucketFileNames æ¡¶ä¸æä»¶åç§°éå |
| | | * @return å é¤ç»æ |
| | | */ |
| | | public List<DeleteError> removeObjectsResult(String bucketName, List<String> bucketFileNames) { |
| | | Iterable<Result<DeleteError>> results = removeObjects(bucketName, bucketFileNames); |
| | | List<DeleteError> res = new ArrayList<>(); |
| | | for (Result<DeleteError> result : results) { |
| | | try { |
| | | res.add(result.get()); |
| | | } catch (Exception e) { |
| | | throw new UtilException("MinioUtilsï¼ä¸ä¼ æä»¶å·¥å
·ç±»å¼å¸¸"); |
| | | } |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤æä»¶å¯¹è±¡ |
| | | * |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param bucketFileNames æ¡¶ä¸æä»¶åç§°éå |
| | | */ |
| | | private Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> bucketFileNames) { |
| | | List<DeleteObject> dos = bucketFileNames.stream().map(DeleteObject::new).collect(Collectors.toList()); |
| | | return minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build()); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢é¢è§url |
| | | * @param bucketFileName minioæä»¶åç§° |
| | | * @param bucketName å卿¡¶åç§° |
| | | * @param isPreviewExpiry æ¯å¦éè¦è¿ææ¶é´ é»è®¤24å°æ¶ |
| | | * @return |
| | | */ |
| | | public String getPreviewUrl(String bucketFileName, String bucketName, Boolean isPreviewExpiry) { |
| | | if (StringUtils.isNotBlank(bucketFileName)) { |
| | | try { |
| | | minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(bucketFileName).build()); |
| | | // 为falseåªçæ24å°æ¶æææ¶é¿çurl龿¥ï¼å¯ä»¥è®¿é®è¯¥æä»¶ |
| | | if (isPreviewExpiry){ |
| | | return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(bucketFileName).build()); |
| | | }else { |
| | | return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(bucketFileName).expiry(previewExpiry, TimeUnit.HOURS).build()); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new UtilException("MinioUtilsï¼ä¸ä¼ æä»¶å·¥å
·ç±»å¼å¸¸"); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |