CSS的三大特性(继承、层叠和优先级)
850 2023-04-03 04:18:17
个人编写整合仅供参考!
出事概不负责!
1.pom.xml
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency>
2.application.yml
#请把下面的配置换成自己的服务器minio: endpoint: http://127.0.0.1:9000 #minio地址 accessKey: minioadmin #minio账号 secretKey: minioadmin #minio密码 bucketName: tong #minio桶名称
3.config
package com.xxx.web.minio;import com.xxx.common.utils.minio.MinioUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @author lishiheng * @create 2022-05-12 11:44 */@Configurationpublic class MinioConfig { /** * 设置请求的统一前缀 */ @Value("${minio.endpoint}") private String endpoint; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Value("${minio.bucketName}") private String bucketName; @Bean public void minioInit() { MinioUtils.init(endpoint, bucketName, accessKey, secretKey); }}
4.utils
package com.xxx.common.utils.minio;import com.alibaba.fastjson.JSONObject;import io.minio.*;import io.minio.errors.*;import io.minio.messages.Bucket;import io.minio.messages.DeleteObject;import io.minio.messages.Item;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.apache.commons.compress.utils.IOUtils;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.time.ZonedDateTime;import java.util.*;/** * @Description: Minio工具类 */@Slf4jpublic class MinioUtils { private static final String SEPARATOR = "/"; public static String endpoint; public static String bucketName; public static String accessKey; public static String secretKey; private static MinioClient minioClient; private MinioUtils() { } public static void init(String endpoint, String bucketName, String accessKey, String secretKey) { String borderStr = "|-------------------------------------------------------------------------------------------|"; System.out.println(borderStr); System.out.println(" minio地址:" + endpoint); System.out.println(" minio桶名称:" + bucketName); System.out.println(" minio账号:" + accessKey); System.out.println(borderStr); MinioUtils.endpoint = endpoint; MinioUtils.bucketName = bucketName; MinioUtils.accessKey = accessKey; MinioUtils.secretKey = secretKey; createMinioClient(); } /** * 创建minioClient */ public static void createMinioClient() { try { if (null == minioClient) { minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build(); createBucket(); } } catch (Exception e) { log.error("==== minio info => ", e); } } /** * 获取上传文件的基础路径 * * @return url */ public static String getBasisUrl() { return endpoint + SEPARATOR + bucketName + SEPARATOR; } /** * 初始化Bucket * * @throws Exception 异常 */ private static void createBucket() { try { if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); } } catch (Exception e) { log.error("==== minio info => ", e); } } /** * 验证bucketName是否存在 * * @return boolean true:存在 */ public static boolean bucketExists() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); } /** * 创建bucket * * @param bucketName bucket名称 */ public static void createBucket(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, RegionConflictException { if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); } } /** * 获取全部bucket * <p> * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets */ public static List<Bucket> getAllBuckets() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.listBuckets(); } /** * 根据bucketName获取信息 * * @param bucketName bucket名称 */ public static Optional<Bucket> getBucket(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst(); } /** * 根据bucketName删除信息 * * @param bucketName bucket名称 */ public static void removeBucket(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build()); } /** * 判断文件是否存在 * * @param bucketName 存储桶 * @param objectName 对象 * @return true:存在 */ public static boolean doesObjectExist(String bucketName, String objectName) { boolean exist = true; try { minioClient .statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()); } catch (Exception e) { exist = false; } return exist; } /** * 判断文件夹是否存在 * * @param bucketName 存储桶 * @param objectName 文件夹名称(去掉/) * @return true:存在 */ public static boolean doesFolderExist(String bucketName, String objectName) { boolean exist = false; try { Iterable<Result<Item>> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build()); for (Result<Item> result : results) { Item item = result.get(); if (item.isDir() && objectName.equals(item.objectName())) { exist = true; } } } catch (Exception e) { exist = false; } return exist; } /** * 根据文件前置查询文件 * * @param bucketName bucket名称 * @param prefix 前缀 * @param recursive 是否递归查询 * @return MinioItem 列表 */ public static List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { List<Item> list = new ArrayList<Item>(); Iterable<Result<Item>> objectsIterator = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build()); if (objectsIterator != null) { for (Result<Item> o : objectsIterator) { Item item = o.get(); list.add(item); } } return list; } /** * 获取文件流 * * @param bucketName bucket名称 * @param objectName 文件名称 * @return 二进制流 */ public static InputStream getObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient .getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); } /** * 获取路径下文件列表 * * @param bucketName bucket名称 * @param prefix 文件名称 * @param recursive 是否递归查找,如果是false,就模拟文件夹结构查找 * @return 二进制流 */ public static Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) { return minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build()); } /** * 通过MultipartFile,上传文件 * * @param bucketName 存储桶 * @param file 文件 * @param objectName 对象名 */ public static ObjectWriteResponse putObject(String bucketName, MultipartFile file, String objectName, String contentType) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { InputStream inputStream = file.getInputStream(); return minioClient.putObject( PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType) .stream( inputStream, inputStream.available(), -1) .build()); } /** * 上传本地文件 * * @param bucketName 存储桶 * @param objectName 对象名称 * @param fileName 本地文件路径 */ public static ObjectWriteResponse putObject(String bucketName, String objectName, String fileName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.uploadObject( UploadObjectArgs.builder() .bucket(bucketName).object(objectName).filename(fileName).build()); } /** * 通过流上传文件 * * @param bucketName 存储桶 * @param objectName 文件对象 * @param inputStream 文件流 */ public static ObjectWriteResponse putObject(String bucketName, String objectName, InputStream inputStream) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.putObject( PutObjectArgs.builder().bucket(bucketName).object(objectName).stream( inputStream, inputStream.available(), -1) .build()); } /** * 创建文件夹或目录 * * @param bucketName 存储桶 * @param objectName 目录路径 */ public static ObjectWriteResponse putDirObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.putObject( PutObjectArgs.builder().bucket(bucketName).object(objectName).stream( new ByteArrayInputStream(new byte[]{}), 0, -1) .build()); } /** * 获取文件信息, 如果抛出异常则说明文件不存在 * * @param bucketName bucket名称 * @param objectName 文件名称 */ public static ObjectStat statObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient .statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()); } /** * 拷贝文件 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param srcBucketName 目标bucket名称 * @param srcObjectName 目标文件名称 */ public static ObjectWriteResponse copyObject(String bucketName, String objectName, String srcBucketName, String srcObjectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.copyObject( CopyObjectArgs.builder() .source(CopySource.builder().bucket(bucketName).object(objectName).build()) .bucket(srcBucketName) .object(srcObjectName) .build()); } /** * 删除文件 * * @param bucketName bucket名称 * @param objectName 文件名称 */ public static void removeObject(String bucketName, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { minioClient .removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build()); } /** * 批量删除文件 * * @param bucketName bucket * @param keys 需要删除的文件列表 * @return */ /*public static Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> keys) { List<DeleteObject> objects = new LinkedList<>(); keys.forEach(s -> { objects.add(new DeleteObject(s)); }); return minioClient.removeObjects( RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build()); }*/ public static void removeObjects(String bucketName, List<String> keys) { List<DeleteObject> objects = new LinkedList<DeleteObject>(); keys.forEach(s -> { objects.add(new DeleteObject(s)); try { removeObject(bucketName, s); } catch (Exception e) { log.error("批量删除失败!error:{}", e); } }); } /** * 获取文件外链 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param expires 过期时间 <=7 秒级 * @return url */ public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, InvalidExpiresRangeException, ServerException, InternalException, NoSuchAlgorithmException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.presignedGetObject(bucketName, objectName, expires); } /** * 给presigned URL设置策略 * * @param bucketName 存储桶 * @param objectName 对象名 * @param expires 过期策略 * @return map */ public static Map<String, String> presignedGetObject(String bucketName, String objectName, Integer expires) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, InvalidExpiresRangeException, ServerException, InternalException, NoSuchAlgorithmException, XmlParserException, InvalidBucketNameException, ErrorResponseException { PostPolicy policy = new PostPolicy(bucketName, objectName, ZonedDateTime.now().plusDays(7)); policy.setContentType("image/png"); return minioClient.presignedPostPolicy(policy); } /** * 将URLDecoder编码转成UTF8 * * @param str * @return * @throws UnsupportedEncodingException */ public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException { String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); return URLDecoder.decode(url, "UTF-8"); } /** * 下载文件 * <p> * bucketName: * 桶名 * * @param fileName: 文件名 * @param response: * @return: void * @date : 2020/8/17 0:34 */ @SneakyThrows(Exception.class) public static void download(String fileName, HttpServletResponse response) { // 获取对象的元数据 final ObjectStat stat = minioClient.statObject(bucketName, fileName); response.setContentType(stat.contentType()); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); InputStream is = minioClient.getObject(bucketName, fileName); IOUtils.copy(is, response.getOutputStream()); is.close(); } /** * 获取存储桶策略 * * @param bucketName 存储桶名称 * @return json */ private JSONObject getBucketPolicy(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException { String bucketPolicy = minioClient .getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build()); return JSONObject.parseObject(bucketPolicy); } /** * 断点下载 * * @param bucketName bucket名称 * @param objectName 文件名称 * @param offset 起始字节的位置 * @param length 要读取的长度 * @return 流 */ public InputStream getObject(String bucketName, String objectName, long offset, long length) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException { return minioClient.getObject( GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length) .build()); }}
5.Controller
package com.xxx.web.controller.minio;import cn.hutool.core.date.DateUtil;import com.xxx.business.minio.MinioInfo;import com.xxx.common.core.domain.AjaxResult;import com.xxx.common.utils.minio.MinioUtils;import io.minio.ObjectWriteResponse;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.v3.oas.annotations.Operation;import lombok.extern.slf4j.Slf4j;import org.apache.commons.io.IOUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.InputStream;import java.io.OutputStream;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.UUID;@RestController@Slf4j@Api(tags = "上传下载文件")public class UpDownLoadController { /** * 上传 * * @param file * @return */ @Operation(summary = "上传文件") @RequestMapping("/minio/upload") public AjaxResult upload(@RequestParam("file") MultipartFile file) { try { String oleFileName = file.getOriginalFilename(); if (StringUtils.isEmpty(oleFileName)) { return AjaxResult.error("文件上传失败"); } String suffix = oleFileName.substring(oleFileName.lastIndexOf(".")); String fileName = MinioUtils.bucketName + "/" + DateUtil.format(new Date(), "yyyyMMdd") + "/" + UUID.randomUUID().toString().replace("-", "") + suffix; ObjectWriteResponse objectWriteResponse = MinioUtils.putObject(MinioUtils.bucketName, file, fileName, file.getContentType()); Map<String, String> res = new HashMap<>(); res.put("url", objectWriteResponse.object()); /* String exLink=MinioUtils.getPresignedObjectUrl(MinioUtils.bucketName,fileName,60*60*24*7); res.put("dep_id",oleFileName); res.put("url",exLink); */ return AjaxResult.success(res); } catch (Exception e) { return AjaxResult.error("上传文件异常:" + e.getMessage()); } } @Operation(summary = "查看流") @RequestMapping("/minio/getUrl") public AjaxResult getUrl(@RequestBody(required = false) MinioInfo minioInfo) { try { Map<String, String> res = new HashMap<>(); String fileName = minioInfo.getTag(); if (StringUtils.isNotBlank(fileName)) { // 5分钟访问时间 String exLink = MinioUtils.getPresignedObjectUrl(MinioUtils.bucketName, fileName, 60 * 5); res.put("url", exLink); return AjaxResult.success(res); } else { return AjaxResult.error("请上传后在下载"); } } catch (Exception e) { return AjaxResult.error("异常:" + e.getMessage()); } } /** * 查看文件 * * @param * @return */ @Operation(summary = "查看流") @RequestMapping("/minio/view") public String view(HttpServletResponse response, MinioInfo minioInfo) { String url = minioInfo.getTag(); OutputStream out = null; try { InputStream inputStream = MinioUtils.getObject(MinioUtils.bucketName, url); if (null != inputStream) { byte[] bytes = IOUtils.toByteArray(inputStream); out = response.getOutputStream(); out.write(bytes); } else { return "文件数据丢失"; } } catch (Exception e) { return "文件读取失败"; } return ""; } //此处的fileName是上传之后返回的路径 @ApiOperation(value = "下载文件") @GetMapping(value = "/minio/download") public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) { MinioUtils.download(fileName, response); }}
6.info
package com.ruoyi.business.minio;import lombok.Data;/** * @author lishiheng * @create 2022-05-12 11:28 */@Datapublic class MinioInfo { private String tag;}
本人这边常用的两个接口
1.上传:/minio/upload
上传完成会返回一个路径,把当前路径存到数据库就可以了。
2.下载:/minio/getUrl
传参是上传返回的路径
访问完成会返回一个临时访问的路径
前端使用 windows.open打开这个路径就可以完成下载