一、备注
1、ObjectBasicInfo、ObjectDetailInfo、ResultBody这三个类可自行替换或者去掉
二、工具类
package com.xxx.util;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.xxx.entity.huarun.ObjectBasicInfo;
import com.xxx.entity.huarun.ObjectDetailInfo;
import com.xxx.entity.huarun.ResultBody;
import com.hitachivantara.common.util.DatetimeFormat;
import com.hitachivantara.core.http.Protocol;
import com.hitachivantara.core.http.client.ClientConfiguration;
import com.hitachivantara.hcp.build.HCPClientBuilder;
import com.hitachivantara.hcp.build.HCPNamespaceClientBuilder;
import com.hitachivantara.hcp.common.auth.LocalCredentials;
import com.hitachivantara.hcp.standard.api.HCPNamespace;
import com.hitachivantara.hcp.standard.api.event.ListObjectHandler;
import com.hitachivantara.hcp.standard.define.NextAction;
import com.hitachivantara.hcp.standard.model.HCPObject;
import com.hitachivantara.hcp.standard.model.HCPObjectSummary;
import com.hitachivantara.hcp.standard.model.request.impl.CopyObjectRequest;
import com.hitachivantara.hcp.standard.model.request.impl.ListObjectRequest;
import com.obs.services.ObsClient;
import com.obs.services.model.HeaderResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.web.multipart.MultipartFile;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* 华润对象存储(OBS)-工具类
*
* @author hcs
* @date 2023/6/20 17:03
*/
@Slf4j
public class HuaRunOBSUtil {
/**
* 文件外链过期时间,7天
*/
private static long expire = 7 * 24 * 60 * 60;
/**
* 文件外链访问端口
*/
private static String port = "";
private static RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
private static String bucketName;
private static String ak;
private static String sk;
private static String endPoint;
private static String targetDomainName;
private static String replaceDomainName;
/**
* OBS操作客户端
*/
private static HCPNamespace obsClient = null;
/**
* 上传、下载文件时使用以下对象
*
* 解决报错:Received fatal alert: protocol_version
*
* 华润对象存储的服务器支持TLSv1.2(使用tcpdump命令抓包看到的)
*/
private static AmazonS3 S3APIClient;
//private static AmazonS3 hs3Client;
/**
* OBS操作客户端Map,key=bucketName,value=客户端
*/
private static Map<String, HCPNamespace> obsClientMap = new HashMap<>();
private static final String SEPARATOR = "/";
public HuaRunOBSUtil(String bucketName, String ak, String sk, String endPoint, String port) {
HuaRunOBSUtil.bucketName = bucketName;
HuaRunOBSUtil.ak = ak;
HuaRunOBSUtil.sk = sk;
HuaRunOBSUtil.endPoint = endPoint;
if (StringUtils.isNotBlank(port)) {
HuaRunOBSUtil.port = ":" + port;
}
createObsClientInstance();
S3APIClient = getInstance(endPoint, ak, sk, "S3SignerType", getHttpProtocol(endPoint));
}
public static String getBucketName() {
return bucketName;
}
public static String getAk() {
return ak;
}
public static String getSk() {
return sk;
}
public static String getEndPoint() {
return endPoint;
}
public static synchronized AmazonS3 getInstance(String endpoint, String ak, String sk,
String signature, String protocol) {
synchronized (AmazonS3.class) {
if (null == S3APIClient) {
S3APIClient = getHCPCSS3Client(endpoint, ak, sk, signature, protocol);
}
}
return S3APIClient;
}
/**
* 获取亚马逊S3客户端
*
* @param endpoint
* @param ak
* @param sk
* @param signature S3SignerType - 表示V2
* AWSS3V4SignerType - 表示V4
* @param protocol
* @return
*/
private static AmazonS3 getHCPCSS3Client(String endpoint, String ak, String sk, String signature, String protocol) {
log.info("开始\t创建S3客户端");
com.amazonaws.ClientConfiguration clientConfig = new com.amazonaws.ClientConfiguration();
//使用HTTP或HTTPS协议
if (protocol.toUpperCase().equals("HTTP")) {
clientConfig.setProtocol(com.amazonaws.Protocol.HTTP);
} else {
clientConfig.setProtocol(com.amazonaws.Protocol.HTTPS);
try {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build(),
/**
* 仅指定TLSv1.2协议,解决报错:Received fatal alert: protocol_version
*
* 如果加上其他版本的协议,有可能会报错:Received fatal alert: protocol_version
*
* 例如指定为TLSv1.1,使用tcpdump命令抓包时如果发现TLSv1.2,则该次交互时失败的
*/
new String[]{"TLSv1.2"},
// For Java 1.7 , 1.8
//new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"},
// For Java1.6-1.7
//new String[] { "TLSv1" },
new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA"},
NoopHostnameVerifier.INSTANCE);
clientConfig.getApacheHttpClientConfig().setSslSocketFactory(sslsf);
} catch (Exception e) {
log.error("创建S3客户端出现异常:" + e.getMessage(), e);
}
}
//连接池的连接数
clientConfig.setMaxConnections(50);
//V2签名 或 V4签名
//S3SignerType - 表示V2
//AWSS3V4SignerType - 表示V4
clientConfig.setSignerOverride(signature);
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withClientConfiguration(clientConfig)
/**
* 以下配置为false:外链格式:存储桶.endpoint/目录/文件名
* 以下配置为true:外链格式:endpoint/存储桶/目录/文件名
*/
//.withPathStyleAccessEnabled(true)
.withEndpointConfiguration(new com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration(endpoint, null))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(ak, sk)))
.build();
log.info("成功\t创建S3客户端");
return client;
}
/**
* 获取OBS操作客户端
*
* @return
*/
private static void createObsClientInstance() {
try {
if (obsClient == null) {
synchronized (ObsClient.class) {
if (obsClient == null) {
log.info("createObsClientInstance--->bucketName={},ak={},sk={},endPoint={}", bucketName, ak, sk, endPoint);
ClientConfiguration clientConfig = new ClientConfiguration();
String httpProtocol = getHttpProtocol(endPoint);
clientConfig.setProtocol(httpProtocol.equalsIgnoreCase(Protocol.HTTPS.toString()) ? Protocol.HTTPS : Protocol.HTTP);
HCPNamespaceClientBuilder builder = HCPClientBuilder.defaultHCPClient();
obsClient = builder.withClientConfiguration(clientConfig)
.withCredentials(new LocalCredentials(ak, sk))
// 去除http协议
.withEndpoint(endPoint.replace(getHttpProtocol(endPoint) + "://", ""))
.withNamespace(bucketName)
.bulid();
obsClientMap.put(bucketName, obsClient);
}
}
}
} catch (Exception e) {
log.error("连接华润对象存储服务器异常:" + e.getMessage(), e);
}
}
/**
* 获取上传文件的基础路径
*
* @return url
*/
public static String getBasisUrl() {
//实示例:http协议 + 存储桶名称 + . + endPoint + port + /
String basisUrl = getHttpProtocol(endPoint) + "://" + bucketName + "." + endPoint.replace(getHttpProtocol(endPoint) + "://", "") + (StringUtils.isNotBlank(port) ? port + SEPARATOR : "");
log.info("getBasisUrl--->" + basisUrl);
basisUrl = replaceDomainName(basisUrl);
return basisUrl;
}
/**
* 获取上传文件的基础路径
*
* @param bucketName
* @return
*/
public static String getBasisUrl(String bucketName) {
//实示例:http协议 + 存储桶名称 + . + endPoint + port + /
String basisUrl = getHttpProtocol(endPoint) + "://" + bucketName + "." + endPoint.replace(getHttpProtocol(endPoint) + "://", "") + (StringUtils.isNotBlank(port) ? port + SEPARATOR : "");
log.info("getBasisUrl2--->" + basisUrl);
basisUrl = replaceDomainName(basisUrl);
return basisUrl;
}
/**
* 根据url地址获取存储桶名称
*
* @param url
* @return
*/
public static String getBucketNameByUrl(String url) {
if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(getHttpProtocol(endPoint))
&& url.contains(endPoint.replace(getHttpProtocol(endPoint) + "://", ""))) {
String str = url.replace(getHttpProtocol(endPoint) + "://", "");
return str.substring(0, str.indexOf("."));
} else {
// 华润只会使用一个存储桶(访问外链替换了域名导致不支持多个存储桶),这里直接返回
log.info("getBucketNameByUrl--->返回默认存储桶" + HuaRunOBSUtil.bucketName);
return HuaRunOBSUtil.bucketName;
}
}
/**
* 获取区域
*
* @param endPoint
* @return
*/
public static String getRegion(String endPoint) {
String substring = endPoint.substring(endPoint.indexOf(".") + 1);
return substring.substring(0, substring.indexOf("."));
}
/**
* 获取http协议
*
* @param endPoint
* @return
*/
public static String getHttpProtocol(String endPoint) {
return endPoint.substring(0, endPoint.indexOf(":"));
}
/**
* 创建存储桶(不确定以下方式是否有用)
*
* @param bucketName
* @return
*/
public static void createBucket(String bucketName, String endPoint) {
try {
log.info("createBucket.bucketName--->" + bucketName);
log.info("createBucket.endPoint--->" + endPoint);
if (!headBucket(bucketName)) {
ClientConfiguration clientConfig = new ClientConfiguration();
String httpProtocol = getHttpProtocol(endPoint);
clientConfig.setProtocol(httpProtocol.equalsIgnoreCase(Protocol.HTTPS.toString()) ? Protocol.HTTPS : Protocol.HTTP);
HCPNamespaceClientBuilder builder = HCPClientBuilder.defaultHCPClient();
HCPNamespace obsClient = builder.withClientConfiguration(clientConfig)
.withCredentials(new LocalCredentials(ak, sk))
// 去除http协议
.withEndpoint(endPoint.replace(getHttpProtocol(endPoint) + "://", ""))
.withNamespace(bucketName)
.bulid();
obsClientMap.put(bucketName, obsClient);
}
} catch (Exception e) {
log.error("createBucket出现异常:" + e.getMessage(), e);
}
}
/**
* 创建存储桶
*
* @param bucketName
* @return
*/
public static void createBucket(String bucketName) {
try {
log.info("createBucket.bucketName--->" + bucketName);
if (!headBucket(bucketName)) {
S3APIClient.createBucket(bucketName);
}
} catch (Exception e) {
log.error("createBucket出现异常:" + e.getMessage(), e);
}
}
/**
* 删除存储桶
*
* @param bucketName
* @return
*/
public static void deleteBucket(String bucketName) {
S3APIClient.deleteBucket(bucketName);
}
/**
* 判断存储桶是否存在
*
* @param bucketName
* @return
*/
public static boolean headBucket(String bucketName) {
try {
return obsClient.doesNamespacesExist(bucketName);
} catch (Exception e) {
log.error("headBucket出现异常:" + e.getMessage(), e);
}
return false;
}
/**
* 上传字符
*
* @param bucketName
* @param objectName
* @param content
* @return
*/
public static ResultBody putObjectByStr(String bucketName, String objectName, String content) {
log.info("putObjectByStr--->bucketName={},objectName={},content={}", bucketName, objectName, content);
if (StringUtils.isBlank(content)) {
return null;
}
//重新构建objectName
objectName = buildObjectName(objectName);
String errorMsg = "";
for (int i = 0; i < 3; i++) {
try {
S3APIClient.putObject(bucketName, objectName, content);
return ResultBody.success(new ObjectBasicInfo("putObjectByStr", objectName));
} catch (Exception e) {
log.error("putObjectByStr出现异常:" + e.getMessage(), e);
errorMsg = e.getMessage();
}
}
return ResultBody.failure(errorMsg);
}
/**
* 上传输入流
*
* @param bucketName
* @param objectName
* @param inputStream
* @return
*/
public static ResultBody putObjectByInput(String bucketName, String objectName, InputStream inputStream) {
log.info("putObjectByInput--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
String errorMsg = "";
ObjectMetadata metadata = new ObjectMetadata();
for (int i = 0; i < 3; i++) {
try {
metadata.setContentLength(inputStream.available());
S3APIClient.putObject(bucketName, objectName, inputStream, metadata);
return ResultBody.success(new ObjectBasicInfo("inputStream", objectName));
} catch (Exception e) {
log.error("第" + (i + 1) + "次putObjectByInput出现异常:" + e.getMessage(), e);
errorMsg = e.getMessage();
}
}
return ResultBody.failure(errorMsg);
}
/**
* 上传文件输入流
*
* @param bucketName
* @param objectName
* @param fileInputStream
* @return
*/
public static ResultBody putObjectByFileInput(String bucketName, String objectName, FileInputStream fileInputStream) {
log.info("putObjectByFileInput--->bucketName={},objectName={}", bucketName, objectName);
return putObjectByInput(bucketName, objectName, fileInputStream);
}
/**
* 通过MultipartFile,上传文件
*
* @param bucketName
* @param objectName
* @param media
* @return
*/
public static ResultBody putObjectByMultipartFile(String bucketName, String objectName, MultipartFile media) throws IOException {
log.info("putObjectByMultipartFile--->bucketName={},objectName={}", bucketName, objectName);
return putObjectByInput(bucketName, objectName, media.getInputStream());
}
/**
* 上传本地文件
*
* @param bucketName
* @param objectName
* @param file
* @return
*/
public static ResultBody putObjectByFile(String bucketName, String objectName, File file) {
log.info("putObjectByFile--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
String errorMsg = "";
for (int i = 0; i < 3; i++) {
try {
S3APIClient.putObject(bucketName, objectName, file);
return ResultBody.success(new ObjectBasicInfo(file.getName(), objectName));
} catch (Exception e) {
log.error("第" + (i + 1) + "次putObjectByFile出现异常:" + e.getMessage(), e);
errorMsg = e.getMessage();
}
}
return ResultBody.failure(errorMsg);
}
/**
* 下载文件到本地
*
* @param bucketName
* @param objectName
* @param filePath
* @return
*/
public static boolean downloadObject(String bucketName, String objectName, String filePath) throws Exception {
log.info("downloadObject--->bucketName={},objectName={},filePath={}", bucketName, objectName, filePath);
if (StringUtils.isBlank(filePath)) {
return false;
}
//重新构建objectName
objectName = buildObjectName(objectName);
filePath = filePath.replace("\\", SEPARATOR);
InputStream input = null;
FileOutputStream fileOutputStream = null;
try {
S3Object obsObject = null;
for (int i = 0; i < 3; i++) {
try {
// 获取对象
obsObject = S3APIClient.getObject(bucketName, objectName);
break;
} catch (Exception e) {
log.error("第" + (i + 1) + "次downloadObject出现异常:" + e.getMessage(), e);
}
}
// 读取对象内容
input = obsObject.getObjectContent();
if (input == null) {
return false;
}
//获取文件夹路径
if (filePath.contains(SEPARATOR)) {
String dir = filePath.substring(0, filePath.lastIndexOf(SEPARATOR));
File difFile = new File(dir);
if (!difFile.exists()) {
//创建文件夹
boolean mkdirs = difFile.mkdirs();
}
}
File file = new File(filePath);
fileOutputStream = new FileOutputStream(file);
byte[] b = new byte[1024];
int len;
while ((len = input.read(b)) != -1) {
fileOutputStream.write(b, 0, len);
}
return true;
} finally {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (input != null) {
input.close();
}
}
}
/**
* 获取文件内容
*
* @param bucketName
* @param objectName
* @return
*/
public static String getObjectContent(String bucketName, String objectName) throws IOException {
log.info("getObjectContent--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
InputStream input = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
for (int i = 0; i < 3; i++) {
try {
// 读取对象内容
input = S3APIClient.getObject(bucketName, objectName).getObjectContent();
break;
} catch (Exception e) {
log.error("第" + (i + 1) + "次getObjectContent出现异常:" + e.getMessage(), e);
}
}
byte[] b = new byte[1024];
int len;
while ((len = input.read(b)) != -1) {
bos.write(b, 0, len);
}
return new String(bos.toByteArray());
} catch (Exception e) {
log.error("getObjectContent出现异常:" + e.getMessage(), e);
} finally {
bos.close();
if (input != null) {
input.close();
}
}
return null;
}
/**
* 获取文件输入流
*
* @param bucketName
* @param objectName
* @return
*/
public static InputStream getObject(String bucketName, String objectName) {
log.info("getObject--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
for (int i = 0; i < 3; i++) {
try {
S3Object object = S3APIClient.getObject(bucketName, objectName);
return object.getObjectContent();
} catch (Exception e) {
log.error("第" + (i + 1) + "次getObject出现异常:" + e.getMessage(), e);
}
}
return null;
}
/**
* 列举指定目录的全部对象
*
* @param bucketName
* @param directoryPath
* @return
*/
public static ResultBody listAllObjects(String bucketName, String directoryPath) {
log.info("listAllObjects--->bucketName={},directoryPath={}", bucketName, directoryPath);
List<ObjectDetailInfo> objList = new ArrayList<>();
try {
HCPNamespace obsClient = obsClientMap.get(bucketName);
ListObjectRequest request = new ListObjectRequest(directoryPath)
.withRecursiveDirectory(true);
obsClient.listObjects(request, new ListObjectHandler() {
@Override
public NextAction foundObject(HCPObjectSummary obj) {
ObjectDetailInfo objInfo = new ObjectDetailInfo(obj.getName(),
obj.getKey(),
obj.getSize(),
obj.getType(),
DatetimeFormat.ISO8601_DATE_FORMAT.format(new Date(obj.getChangeTime())),
obj.getContentHash());
objList.add(objInfo);
return null;
}
});
} catch (Exception e) {
log.error("listAllObjects出现异常:" + e.getMessage(), e);
return ResultBody.failure(e.getMessage());
}
return ResultBody.success(objList);
}
/**
* 删除单个对象
*
* @param bucketName
* @param objectName
* @return
*/
public static ResultBody deleteObject(String bucketName, String objectName) {
log.info("deleteObject--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
try {
HCPNamespace obsClient = obsClientMap.get(bucketName);
obsClient.deleteObject(bucketName, objectName);
return ResultBody.success();
} catch (Exception e) {
log.error("deleteObject出现异常:" + e.getMessage(), e);
return ResultBody.failure(e.getMessage());
}
}
/**
* 复制对象
*
* @param sourceBucketName
* @param sourceObjectName
* @param destBucketName
* @param destObjectName
* @return
*/
public static boolean copyObject(String sourceBucketName, String sourceObjectName,
String destBucketName, String destObjectName) {
log.info("deleteObject--->sourceBucketName={},sourceObjectName={},destBucketName={},destObjectName={}", bucketName, sourceObjectName, destBucketName, destObjectName);
CopyObjectRequest copyObjectRequest = new CopyObjectRequest();
copyObjectRequest.withSourceNamespace(sourceBucketName);
copyObjectRequest.withSourceKey(sourceObjectName);
copyObjectRequest.withTargetNamespace(destBucketName);
copyObjectRequest.withTargetKey(destObjectName);
try {
obsClient.copyObject(copyObjectRequest);
return true;
} catch (Exception e) {
log.error("copyObject出现异常:" + e.getMessage(), e);
}
return false;
}
/**
* 判断对象是否存在
*
* @param bucketName
* @param objectName
* @return
*/
public static boolean doesObjectExist(String bucketName, String objectName) {
log.info("deleteObject--->bucketName={},objectName={}", bucketName, objectName);
//重新构建objectName
objectName = buildObjectName(objectName);
try {
HCPNamespace obsClient = obsClientMap.get(bucketName);
return obsClient.doesObjectExist(objectName);
} catch (Exception e) {
log.error("doesObjectExist出现异常:" + e.getMessage(), e);
}
return false;
}
/**
* 获取文件外链
*
* @param bucketName
* @param objectName
* @param expires 单位:秒(s)
* @return
*/
public static String getSignedUrl(String bucketName, String objectName, Long expires) {
log.info("getSignedUrl--->bucketName={},objectName={},expires={}", bucketName, objectName, expires);
//重新构建objectName
objectName = buildObjectName(objectName);
Date expiration = new Date(System.currentTimeMillis() + (expires * 1000));
try {
//String e = endPoint.replace(getHttpProtocol(endPoint) + "://", "");
//AmazonS3 hs3Client = newS3Client(e, ak, sk);
// 生成预签名时间
URL url = S3APIClient.generatePresignedUrl(new GeneratePresignedUrlRequest(bucketName, objectName).withExpiration(expiration).withMethod(HttpMethod.GET));
String s = url.toString();
log.info("这个是api生成的url------------------------------------>" + s);
// 由于api返回的是http,这里自行替换为endpoint使用的协议
s = s.replace(getHttpProtocol(s) + "://", getHttpProtocol(endPoint) + "://");
log.info("替换协议后url------>" + s);
s = replaceDomainName(s);
return s;
} catch (Exception e) {
log.error("getSignedUrl出现异常:" + e.getMessage(), e);
}
return null;
}
/**
* 获取文件外链-url有效时间默认7天
*
* @param bucketName
* @param objectName
* @return
*/
public static String getSignedUrl(String bucketName, String objectName) {
return getSignedUrl(bucketName, objectName, expire);
}
/**
* 重新构建objectName
*
* @param objectName
*/
private static String buildObjectName(String objectName) {
if (StringUtils.isBlank(objectName)) {
return objectName;
}
//去除开头的/
objectName = objectName.startsWith("/") ? objectName.substring(1) : objectName;
//去除?后边的参数
objectName = objectName.contains("?") ? objectName.substring(0, objectName.indexOf("?")) : objectName;
return objectName;
}
/**
* 传入文件访问外链,返回objectName
*
* @param url
* @return
*/
public static String getObjectNameByUrl(String url) {
if (StringUtils.isBlank(url)) {
return url;
}
try {
url = URLDecoder.decode(url, "UTF-8");
} catch (Exception e) {
log.error("getObjectNameByUrl获取文件外链失败:" + e.getMessage(), e);
}
if (url.contains(getBasisUrl())) {
// 去除基础路径
url = url.replace(getBasisUrl(), "");
// 去除?后边的参数
url = url.contains("?") ? url.substring(0, url.indexOf("?")) : url;
}
return url;
}
/**
* 获取华润OBS文件外链
*
* @param redisKey
* @param objectName
* @return
* @throws Exception
*/
public static String getOBSFileUrl(String redisKey, String objectName) throws Exception {
if (StringUtils.isBlank(objectName) || StringUtils.isBlank(redisKey) || OBSUtil.httpRegex(objectName)) {
return "";
}
objectName = URLDecoder.decode(objectName, "UTF-8");
//重新构建objectName
objectName = buildObjectName(objectName);
Object o = redisUtil.get(redisKey);
String url = o == null ? null : o.toString();
if (StringUtils.isNotBlank(url)) {
return url;
} else {
//重新获取url
String signedUrl = getSignedUrl(getBucketName(), objectName, expire);
//保存访问url,有效期为6天
redisUtil.set(redisKey, signedUrl, 6 * 24 * 60 * 60);
return signedUrl;
}
}
/**
* 从指定存储桶获取华润OBS文件外链
*
* @param redisKey
* @param objectName
* @param bucketName
* @return
* @throws Exception
*/
public static String getOBSFileUrl(String redisKey, String objectName, String bucketName) throws Exception {
if (StringUtils.isBlank(objectName) || StringUtils.isBlank(redisKey) || StringUtils.isBlank(bucketName)) {
return "";
}
//重新构建objectName
objectName = buildObjectName(objectName);
Object o = redisUtil.get(redisKey);
String url = o == null ? null : o.toString();
if (StringUtils.isNotBlank(url)) {
return url;
} else {
//重新获取url
String signedUrl = getSignedUrl(bucketName, objectName, expire);
//保存访问url,有效期为6天
redisUtil.set(redisKey, signedUrl, 6 * 24 * 60 * 60);
return signedUrl;
}
}
/**
* 保存华润OBS文件外链至redis
*
* @param redisKey
* @param url
* @return
*/
public static boolean setOBSFileUrl(String redisKey, String url) {
Object o = redisUtil.get(redisKey);
if (o != null) {
String value = o.toString();
//只保存新的外链,解决url重复保存导致redis保存的是过期外链的问题
if (!value.equals(url)) {
//保存访问url,有效期为6天
return redisUtil.set(redisKey, url, 6 * 24 * 60 * 60);
}
} else {
//保存访问url,有效期为6天
return redisUtil.set(redisKey, url, 6 * 24 * 60 * 60);
}
return true;
}
/**
* 删除华润OBS文件外链
*
* @param redisKey
*/
public static void delOBSFileUrl(String redisKey) {
//删除访问url
redisUtil.del(redisKey);
}
/**
* 替换域名
*
* @param url
* @return
*/
private static String replaceDomainName(String url){
if (StringUtils.isNotBlank(replaceDomainName) && StringUtils.isNotBlank(targetDomainName)) {
url = url.replace(targetDomainName, replaceDomainName);
log.info("替换域名后url------>" + url);
}
return url;
}
public static void setTargetDomainName(String targetDomainName) {
HuaRunOBSUtil.targetDomainName = targetDomainName;
}
public static void setReplaceDomainName(String replaceDomainName) {
HuaRunOBSUtil.replaceDomainName = replaceDomainName;
}
}
三、对象存储放在内网,如何实现外网访问
如果对象存储是放在内网的,可以按照以下示例配置ngin代理
nginx配置请参考:https://app.rwork.crc.com.cn/docs/dock9zVHp5WcpLYNKfjo5ACbU8g
结合代码中的targetDomainName
、replaceDomainName
可实现外网访问
本文含有隐藏内容,请 开通VIP 后查看