com.github.javaclub.ossclient.impl.AliyunOssClient Maven / Gradle / Ivy
The newest version!
package com.github.javaclub.ossclient.impl;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.Duration;
import java.util.Date;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.multipart.MultipartFile;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.github.javaclub.BizException;
import com.github.javaclub.Constants.MemCapacity;
import com.github.javaclub.delaytask.DelayJob;
import com.github.javaclub.delaytask.DelayQueueProducer;
import com.github.javaclub.ossclient.OssClient;
import com.github.javaclub.ossclient.OssConstants;
import com.github.javaclub.ossclient.OssConstants.Aliyun;
import com.github.javaclub.ossclient.event.KeyedImageUploadEvent;
import com.github.javaclub.ossclient.util.AssetsUtils;
import com.github.javaclub.toolbox.ToolBox.Files;
import com.github.javaclub.toolbox.ToolBox.Numbers;
import com.github.javaclub.toolbox.ToolBox.Objects;
import com.github.javaclub.toolbox.ToolBox.Strings;
import com.github.javaclub.toolbox.ToolBox.UUID;
import com.github.javaclub.toolbox.conf.CompositeAppConfigProperties;
import com.github.javaclub.toolbox.spring.BeanFactory;
import com.github.javaclub.toolbox.utils.ThreadLocalDateFormatter;
public class AliyunOssClient implements OssClient, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(AliyunOssClient.class);
private String endpoint;
private String accessKey;
private String secretKey;
private String cdnDomain;
private String cdnProtocol;
private String defaultBucket;
private int fileUploadLimitMbSize; // 限制上限为 {xx} MB
private boolean doOriginReferCheck;
private boolean fileArchivedByDate;
@Override
public void afterPropertiesSet() throws Exception {
endpoint = CompositeAppConfigProperties.getInstance().getValue(Aliyun.ENDPOINT);
accessKey = CompositeAppConfigProperties.getInstance().getValue(Aliyun.ACCESS_KEY);
secretKey = CompositeAppConfigProperties.getInstance().getValue(Aliyun.SECRET_KEY);
cdnDomain = CompositeAppConfigProperties.getInstance().getValue(Aliyun.CDN_DOMAIN);
cdnProtocol = CompositeAppConfigProperties.getInstance().getValue(Aliyun.CDN_PROTOCOL);
defaultBucket = CompositeAppConfigProperties.getInstance().getValue(Aliyun.DEFAULT_BUCKET);
fileUploadLimitMbSize = CompositeAppConfigProperties.getInstance().intValue(OssConstants.FILE_UPLOAD_LIMIT_SIZE, 10);
doOriginReferCheck = CompositeAppConfigProperties.getInstance().boolValue(OssConstants.SAME_ORIGIN_CHECK, true);
fileArchivedByDate = CompositeAppConfigProperties.getInstance().boolValue(OssConstants.FILE_ARCHIVED_BY_DATE, true);
String[] array = new String[] {
endpoint, accessKey, secretKey, cdnDomain, cdnProtocol
};
Objects.requireTrue(Strings.areNotBlank(array), "Aliyun Oss 配置参数缺失!");
}
@Override
public String upload(MultipartFile file, String relativePathInBucket, Map params) {
OSS oss = null;
String imageUrl = null;
try {
String originalFilename = file.getOriginalFilename();
String directory = Strings.endsWithIgnoreCase(relativePathInBucket, "/") ? relativePathInBucket
: Strings.concat(relativePathInBucket, "/");
if (fileArchivedByDate) {
directory = Strings.concat(directory, ThreadLocalDateFormatter.numericDateFormat(new Date()) , "/");
}
String suffix = originalFilename.substring(originalFilename.lastIndexOf('.')).toLowerCase();
String filename = UUID.randomUUID() + suffix;
AssetsUtils.checkFileExtention(suffix, "aliyun", params);
if (0 < fileUploadLimitMbSize && file.getSize() > MemCapacity.longBytesOfMB(fileUploadLimitMbSize)) { // 文件大小限制
throw new BizException("文件大小超出最大上传限制!");
}
if (doOriginReferCheck) {
// TODO
}
String bucketVar = (String) params.getOrDefault(OssConstants.BUCKET_NAME_PARAM_KEY, Strings.EMPTY);
String bucketName = Strings.isBlank(bucketVar) ? defaultBucket : bucketVar;
String fileObject = Strings.concat(directory, filename);
InputStream input = file.getInputStream();
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType(Files.getFileContentType(suffix));
meta.setContentLength(input.available());
meta.setCacheControl("no-cache");
meta.setHeader("Pragma", "no-cache");
meta.setContentDisposition("inline;filename=" + filename);
oss = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
oss.putObject(bucketName, fileObject, input, meta);
String protocol = Strings.endsWithIgnoreCase(cdnProtocol, "://") ? cdnProtocol : Strings.concat(cdnProtocol, "://");
// 上传得到图片URL地址: {网络协议}{域名}/{文件路径PATH + 文件名}
imageUrl = Strings.format("{}{}/{}", protocol, cdnDomain, fileObject);
DelayQueueProducer delayQueueProducer = getDelayQueueProducer();
if (null != params && null != params.get("key")
&& null != delayQueueProducer) {
String extraKey = Objects.toString(params.get("key"));
KeyedImageUploadEvent event = new KeyedImageUploadEvent(new Date(), extraKey, imageUrl);
DelayJob job = new DelayJob(event);
delayQueueProducer.submit("topic_common", job, Duration.ofMillis(Numbers.random(1L, 10L)));
}
} catch (BizException e) {
throw e;
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new BizException(e);
} finally {
if (null != oss) {
oss.shutdown();
}
}
return imageUrl;
}
@Override
public String upload(byte[] bytes, String filename, Map params) {
OSS oss = null;
String imageUrl = null;
try {
if (null == bytes || 0 >= bytes.length) {
throw new BizException("上传文件不能为空!");
}
if (doOriginReferCheck) {
// TODO
}
if (null != bytes && bytes.length > MemCapacity.longBytesOfMB(fileUploadLimitMbSize)) { // 文件大小限制
throw new BizException("文件大小超出最大上传限制!");
}
String bucketVar = (String) params.getOrDefault(OssConstants.BUCKET_NAME_PARAM_KEY, Strings.EMPTY);
String bucketName = Strings.isBlank(bucketVar) ? defaultBucket : bucketVar;
String filenameLastSegment = filename;
if (filename.lastIndexOf("/") >= 0) {
filenameLastSegment = filename.substring(filename.lastIndexOf("/") + 1);
}
String fileExtention = Files.getExtension(filenameLastSegment);
String contentType = java.util.Objects.toString(params.get(OssConstants.CONTENT_TYPE_PARAM_KEY), Strings.EMPTY);
if (Strings.isBlank(contentType)) {
contentType = Files.getFileContentType(fileExtention);
}
String finalFilename = Strings.concat(UUID.randomUUID(), fileExtention);
String relativePath = Strings.EMPTY;
if (fileArchivedByDate) {
relativePath = Strings.concat(relativePath, ThreadLocalDateFormatter.numericDateFormat(new Date()) , "/");
}
String fileObject = Strings.concat(relativePath, finalFilename);
oss = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
if (Strings.isBlank(contentType)) {
oss.putObject(bucketName, fileObject, new ByteArrayInputStream(bytes));
} else {
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType(contentType);
meta.setContentLength(bytes.length);
meta.setContentDisposition("inline;filename=" + finalFilename);
oss.putObject(bucketName, fileObject, new ByteArrayInputStream(bytes), meta);
}
String protocol = Strings.endsWithIgnoreCase(cdnProtocol, "://") ? cdnProtocol : Strings.concat(cdnProtocol, "://");
// 上传得到图片URL地址: {网络协议}{域名}/{文件路径PATH + 文件名}
imageUrl = Strings.format("{}{}/{}", protocol, cdnDomain, fileObject);
DelayQueueProducer delayQueueProducer = getDelayQueueProducer();
if (null != params && null != params.get("key") && null != delayQueueProducer) {
String extraKey = Objects.toString(params.get("key"));
KeyedImageUploadEvent event = new KeyedImageUploadEvent(new Date(), extraKey, imageUrl);
DelayJob job = new DelayJob(event);
delayQueueProducer.submit("topic_common", job, Duration.ofMillis(Numbers.random(1L, 10L)));
}
} catch (BizException e) {
throw e;
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new BizException(e);
} finally {
if (null != oss) {
oss.shutdown();
}
}
return imageUrl;
}
DelayQueueProducer getDelayQueueProducer() {
return BeanFactory.getInstance().getBean(DelayQueueProducer.class);
}
}