All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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);
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy