杭州市江干区建设局网站用dw制作网站模板下载地址
news/
2025/10/7 19:43:39/
文章来源:
杭州市江干区建设局网站,用dw制作网站模板下载地址,宣传片制作费用报价表,上虞区住房和城乡建设局网站文章目录 前言技术回顾准备工作申请accessKey\secretKey创建数据存储桶公共资源直接访问测试 接入springboot实现文件服务依赖引入配置文件MinIO配置MinIO工具类 OkHttpSSLSocketClient兼容ssl静态资源预览解决方案资源上传预览测试测试结果 前言
上篇博客我们介绍了分布式云存… 文章目录 前言技术回顾准备工作申请accessKey\secretKey创建数据存储桶公共资源直接访问测试 接入springboot实现文件服务依赖引入配置文件MinIO配置MinIO工具类 OkHttpSSLSocketClient兼容ssl静态资源预览解决方案资源上传预览测试测试结果 前言
上篇博客我们介绍了分布式云存储MinIO作业环境的搭建以及分布式云储存MinIO在实际的文件服务中的优势。那么今天我们就小试牛刀来将MinIO接入我们的微服务项目实现一个分布式的文件服务器。
技术回顾
MinIO 提供高性能、与S3 兼容的对象存储系统让你自己能够构建自己的私有云储存服务。 MinIO原生支持 Kubernetes它可用于每个独立的公共云、每个 Kubernetes 发行版、私有云和边缘的对象存储套件。 MinIO是软件定义的不需要购买其他任何硬件在 GNU AGPL v3 下是 100% 开源的。
准备工作
申请accessKey\secretKey
MinIO控制台申请accessKey\secretKey http://your_hostname:18001~18004/login minio/minio123
创建数据存储桶
创建数据存储桶
点击创建的桶我们进行访问策略配置
访问策略有private\custom\public public 公共的桶任何人都可以访问资源直接映射为静态资源可直接提供预览和下载 custom 自定义桶用户根据自身需求定义访问规则 private 私有的桶需要授权才能访问
根据一般的生产需求我们定义一个private一个custom桶。private保存私有资源custom保存公共资源并禁止目录访问。
private 规则
custom 规则
{Version: 2012-10-17,Statement: [{Effect: Allow,Principal: {AWS: [*]},Action: [s3:GetBucketLocation,s3:ListBucketMultipartUploads],Resource: [arn:aws:s3:::sacpublic]},{Effect: Allow,Principal: {AWS: [*]},Action: [s3:AbortMultipartUpload,s3:DeleteObject,s3:GetObject,s3:ListMultipartUploadParts,s3:PutObject],Resource: [arn:aws:s3:::sacpublic/*]}]
}公共资源直接访问测试
私有资源代码博文最后测试 公共资源直接访问测试
接入springboot实现文件服务
依赖引入
maven引入依赖
!--minio--
dependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.2.0/version
/dependency
!--minio--配置文件
配置文件
minio.url https://10.10.22.91:9100
minio.accessKey fUIXbkBZ9UQTHOOZXNGW
minio.secretKey sy1RAgItAOk9pk1gE7FbrPYzsZI87CfpGkuoY0KW
minio.buckets.public sacpublic
minio.buckets.private sacprivate注意接口调用minio url 为nginx映射出来的9000端口 http://your_hostname:9000
MinIO配置
MinIO配置
/*** MinioConfig* author senfel* version 1.0* date 2023/9/14 11:37*/
Configuration
ConditionalOnProperty(name oss.file.service, havingValue minio, matchIfMissing true)
public class MinioConfig {Value(${minio.url})private String minioUrl;Value(${minio.accessKey})private String accessKey;Value(${minio.secretKey})private String secretKey;Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}}MinIO工具类
MinIO工具类
/*** MinioUtil* author senfel* version 1.0* date 2023/9/14 10:26*/
Component
ConditionalOnProperty(name oss.file.service, havingValue minio, matchIfMissing true)
public class MinioUtil {Resourceprivate MinioClient minioClient;/*** 创建一个桶*/public void createBucket(String bucket) throws Exception {boolean found minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());if (!found) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());}}/*** 上传一个文件*/public ObjectWriteResponse uploadFile(InputStream stream, String bucket, String objectName) throws Exception {String prefix objectName.substring(objectName.lastIndexOf(.) 1);//静态资源预览解决方案//String contentType ViewContentType.getContentType(prefix);ObjectWriteResponse objectWriteResponse minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).contentType(contentType).stream(stream, -1, 10485760).build());return objectWriteResponse;}/*** 列出所有的桶*/public ListString listBuckets() throws Exception {ListBucket list minioClient.listBuckets();ListString names new ArrayList();list.forEach(b - {names.add(b.name());});return names;}/*** 下载一个文件*/public InputStream download(String bucket, String objectName) throws Exception {InputStream stream minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());return stream;}/*** 删除一个桶*/public void deleteBucket(String bucket) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());}/*** 删除一个对象*/public void deleteObject(String bucket, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());}/*** 复制文件** Param: [sourceBucket, sourceObject, targetBucket, targetObject]* return: void* Date: 2021/11/15*/public void copyObject(String sourceBucket, String sourceObject, String targetBucket, String targetObject) throws Exception {this.createBucket(targetBucket);minioClient.copyObject(CopyObjectArgs.builder().bucket(targetBucket).object(targetObject).source(CopySource.builder().bucket(sourceBucket).object(sourceObject).build()).build());}/*** 获取文件信息** Param: [bucket, objectName]* return: java.lang.String*/public String getObjectInfo(String bucket, String objectName) throws Exception {return minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build()).toString();}/*** 生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载即使其所在的存储桶是私有的。* Param: [bucketName, objectName, expires]* return: java.lang.String*/public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {GetPresignedObjectUrlArgs build GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).method(Method.GET).build();return minioClient.getPresignedObjectUrl(build);}}OkHttpSSLSocketClient兼容ssl
对于改解决方案一般生产环境都有固定的域名和匹配的ssl证书如果也不用https我们代码则不用兼容ssl。但是如果我们配置了不可信任的ssl这里我们则需要进行ssl兼容方案。
/*** MinioConfig* author senfel* version 1.0* date 2023/9/14 11:37*/
Configuration
ConditionalOnProperty(name oss.file.service, havingValue minio, matchIfMissing true)
public class MinioConfig {Value(${minio.url})private String minioUrl;Value(${minio.accessKey})private String accessKey;Value(${minio.secretKey})private String secretKey;Beanpublic MinioClient getMinioClient() {OkHttpClient okHttpClient new OkHttpClient.Builder().sslSocketFactory(OkHttpSSLSocketClient.getSSLSocketFactory(),OkHttpSSLSocketClient.getX509TrustManager()) // //通过sslSocketFactory方法设置https证书.hostnameVerifier(OkHttpSSLSocketClient.getHostnameVerifier()).build();return MinioClient.builder().endpoint(minioUrl).httpClient(okHttpClient).credentials(accessKey, secretKey).build();}}/*** OkHttpSSLSocketClient* author senfel* version 1.0* date 2023/9/15 10:07*/
public class OkHttpSSLSocketClient{//获取SSLSocketFactorypublic static SSLSocketFactory getSSLSocketFactory() {try {SSLContext sslContext SSLContext.getInstance(SSL);sslContext.init(null, getTrustManager(), new SecureRandom());return sslContext.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}//获取TrustManagerprivate static TrustManager[] getTrustManager() {TrustManager[] trustAllCerts new TrustManager[]{new X509TrustManager() {Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}};return trustAllCerts;}//获取HostnameVerifier验证主机名public static HostnameVerifier getHostnameVerifier() {HostnameVerifier hostnameVerifier (s, sslSession) - true;return hostnameVerifier;}//X509TrustManager证书信任器管理类public static X509TrustManager getX509TrustManager() {X509TrustManager x509TrustManager new X509TrustManager() {//检查客户端的证书是否可信Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}//检查服务器端的证书是否可信Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}};return x509TrustManager;}
}静态资源预览解决方案
由于我们使用API上传minio不能区分我们资源的类型如果资源类型不对则不能正确提供预览功能都直接变成为访问资源链接就下载了。
所以在实际的项目集成中我们在上传资源前需要将资源类型写入请求中方便minio解析并提供预览和下载功能。
/*** 上传一个文件*/
public ObjectWriteResponse uploadFile(InputStream stream, String bucket, String objectName) throws Exception {String prefix objectName.substring(objectName.lastIndexOf(.) 1);//静态资源预览解决方案String contentType ViewContentType.getContentType(prefix);ObjectWriteResponse objectWriteResponse minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).contentType(contentType).stream(stream, -1, 10485760).build());return objectWriteResponse;
}/*** ViewContentType* author senfel* version 1.0* date 2023/9/14 17:27*/
public enum ViewContentType {DEFAULT(default,application/octet-stream),JPG(jpg, image/jpeg),TIFF(tiff, image/tiff),GIF(gif, image/gif),JFIF(jfif, image/jpeg),PNG(png, image/png),TIF(tif, image/tiff),ICO(ico, image/x-icon),JPEG(jpeg, image/jpeg),WBMP(wbmp, image/vnd.wap.wbmp),FAX(fax, image/fax),NET(net, image/pnetvue),JPE(jpe, image/jpeg),RP(rp, image/vnd.rn-realpix);private String prefix;private String type;public static String getContentType(String prefix){if(StringUtils.isEmpty(prefix)){return DEFAULT.getType();}prefix prefix.substring(prefix.lastIndexOf(.) 1);for (ViewContentType value : ViewContentType.values()) {if(prefix.equalsIgnoreCase(value.getPrefix())){return value.getType();}}return DEFAULT.getType();}ViewContentType(String prefix, String type) {this.prefix prefix;this.type type;}public String getPrefix() {return prefix;}public String getType() {return type;}
}
资源上传预览测试
MinIO对于图片等资源可以直接预览对于excel文档等直接提供下载功能
SpringBootTest
RunWith(SpringJUnit4ClassRunner.class)
public class CodeDbInfoServiceTests {ResourceLazyprivate MinioUtil minioUtil;/*** upload* author senfel* date 2023/9/27 10:00* return void*/Testpublic void upload() throws Exception {FileInputStream fileInputStream new FileInputStream(C:/Users/dev/Desktop/minio.png);ObjectWriteResponse sacprivate minioUtil.uploadFile(fileInputStream, sacprivate, test/minio.png);System.err.println(sacprivate.bucket());}/*** 获取私库连接* author senfel* date 2023/9/27 10:01* return void*/Testpublic void getPrivateUrl() throws Exception{String url minioUtil.getPresignedObjectUrl(sacprivate, test/minio.png, 60);System.err.println(url);}
}测试结果
图片成功上传
私库直接预览访问失败
获取私库链接过期时间为60s
访问成功
60s后再次访问该链接提示链接已经过期
至此minio接入并测试完成对于公开桶的资源直接可任意访问不用获取有效期链接。
写在最后 Springboot微服务接入MinIO实现文件服务较为简单我们只要按照官方文档引入依赖调用即可。值得注意的是我们根据需求选择接入ssl兼容方案和静态资源预览功能。当然minio的private\custom\public可以完全实现我们各种需求可以完全替代市场上付费和笨重的分布式服务。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930767.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!