对于我们公司来说阿里云的对象储存OSS用的比较多,之前倒是没怎么注意,目前有个需求是需要将前端传来的base64串的图片存储到阿里云上,然后进行支付,支付成功之后,再把照片拿回来,处理一些业务。等于饶了一圈又回来了,没办法,需求有了,那就干吧!

首先贴上OSS的工具类 OSSUtils:

package com.lin.modules.sdk.aliyun;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.lin.common.aspect.ContextLog;
import com.lin.common.exception.CheckException;
import com.lin.common.utils.ImageUtils;


public class  OSSUtils{
	// Endpoint以杭州为例,其它Region请按实际情况填写。
	final static String endpoint = "oss-cn-beijing.aliyuncs.com";
	// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
	final static String accessKeyId = "accessKeyId";
	final static String   accessKeySecret = "accessKeySecret ";
	final static String   bucketName = "bucketName";//桶的名字 即是访问路径前缀
	
	final static String img_url = "http://image.baidu.com";//自定义文件域名 映射到服务器上即可
	
	/**
	 * 基础获取URL的过期时间 : 10分钟
	 */
	final static Long EXPIRESTIME = 1000 * 60 * 10L;
	
	/**
	 * 上传base64的图片到阿里云
	 * @param base64 
	 * @param name 文件名称(带后缀名)
	 */	
	public static void uploadImg(String base64,String name) {
		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		
		// 上传Byte数组。
		byte[] imageBase64ToByteArray = ImageUtils.imageBase64ToByteArray(base64, 1024*1027*4);
		
		ossClient.putObject(bucketName, name, new ByteArrayInputStream(imageBase64ToByteArray));
		
		ContextLog.info("上传图片至阿里云", bucketName + "-" + name, "com.csi.modules.sdk.aliyun.OSSUtils.uploadImg", OSSUtils.class);
		
		// 关闭OSSClient。
		ossClient.shutdown();
	}
	
	/**
	 * 上传文件到阿里云
	 * @param str 字符串
	 * @param name 文件名字
	 */
	public static void upload(String str,String name) {
		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		
		ossClient.putObject(bucketName, name,new ByteArrayInputStream(str.getBytes()));
		// 关闭OSSClient。
		ossClient.shutdown();
	}
	
	/**
	 * 上传流文件
	 * @param inputStream
	 * @param name
	 */
	public static void upload(InputStream inputStream,String name) {
		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		ossClient.putObject(bucketName, name,inputStream);
		// 关闭OSSClient。
		ossClient.shutdown();
	}
	
	/**
	 * 上传PDF文件
	 * @param inputStream
	 * @param name
	 * @param fileName
	 */
	public static void uploadPdf(InputStream inputStream,String name,String fileName) {
		// 创建OSSClient实例。
		// 创建上传Object的Metadata
		ObjectMetadata meta = new ObjectMetadata();
		meta.setContentDisposition("attachment;filename="+fileName+".pdf");
		// 设置上传文件长度
//		meta.setContentLength(content.length());
		// 设置上传MD5校验
//		String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
//		meta.setContentMD5(md5);
		// 设置上传内容类型
//		meta.setContentType("text/plain");
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		ossClient.putObject(bucketName, name,inputStream,meta);
		// 关闭OSSClient。
		ossClient.shutdown();
	}
	
	/**
	 * 获取文件请求路径
	 * @param ObjectName 文件名
	 * @return
	 */
	public static String getUrl(String ObjectName) {
		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		// 设置URL过期时间为1小时。
		Date expiration = new Date(new Date().getTime() + 900 * 1000);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName, ObjectName, expiration);
		// 关闭OSSClient。
		ossClient.shutdown();
		return img_url+url.getFile();
	}
	
	/**
	 * 
	 * @param ObjectName
	 * @param minute 过期时间秒
	 * @return
	 */
	public static String getUrl(String ObjectName,long second) {
		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,accessKeySecret);
		// 设置URL过期时间为1小时。
		Date expiration = new Date(new Date().getTime() + second);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName, ObjectName, expiration);
		// 关闭OSSClient。
		ossClient.shutdown();
		return img_url+url.getFile();
	}
	
	/**
	 * 读取阿里云oss上的照片为base64
	 * @param imagesUrl 图片名称
	 * @return
	 */
	public static String getImage2Base64(String imagesUrl) {
		if (StringUtils.isBlank(imagesUrl)) {
			throw new CheckException("图片地址为空");
		}
		ContextLog.printSeparator("imagesUrl:" + imagesUrl);
		// 指定过期时间为十分钟。
		Date expiration = new Date(new Date().getTime() + EXPIRESTIME);
        
        OSS ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, imagesUrl, HttpMethod.GET);
//        req.setExpiration(expiration);
//        设置图片处理样式。
//        String style = "image/resize,m_fixed,w_200,h_200/rotate,90";
//        req.setProcess(style);
//        URL signedUrl = ossClient.generatePresignedUrl(req);
        
        URL signedUrl = ossClient.generatePresignedUrl(bucketName, imagesUrl, expiration);
        
        //2,得到HttpClient对象
        CloseableHttpClient client = HttpClients.createDefault();//获取DefaultHttpClient请求  使用的仍然是HttpClientBuilder.create().build();
        //3,设置请求方式
        HttpGet get = new HttpGet(signedUrl.toString());
        //4,执行请求, 获取响应信息
        CloseableHttpResponse response = null;
		try {
			response = client.execute(get);
			if(200 != response.getStatusLine().getStatusCode()){
				//System.out.println("获取阿里云人像照片失败:code:" + response.getStatusLine().getStatusCode());
				ContextLog.info("获取阿里云人像照片失败:code:", response.getStatusLine().getStatusCode(), "com.csi.modules.sdk.aliyun.OSSUtils.getImage2Base64", OSSUtils.class);
	        }
			 //得到实体
            HttpEntity entity = response.getEntity();
            byte[] data = EntityUtils.toByteArray(entity);
			//返回Base64编码过的字节数组字符串,无前缀标识,如需要可手动添加“data:image/jpeg;base64,”
			return Base64.encodeBase64String(data);
		} catch (IOException e) {
			ContextLog.error("获取阿里云人像照片转换异常:", e);
		}finally {
			try {
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return "";
	}
	
	public static void main(String[] args) {
		String url = "789359873957547-2020-05-08 09:02:59.jpeg";
		String image2Base64 = getImage2Base64(url);
		System.out.println(image2Base64);
	}
}

ImageUtils

public class ImageUtils {
	public static byte[]  imageBase64ToByteArray(String base64Str,int size) {
		//判断是否包含前缀,去掉前缀
		if (base64Str.contains(",")) {
			base64Str = base64Str.split(",")[1];
		}
		byte[] decodeFromString = Base64.decodeBase64(base64Str);
		//ContextLog.info("验证base64图片大小","base64:"+ base64Str+" 限制大小:"+size, "com.csi.common.utils.ImageUtils.imageBase64Limit", ImageUtils.class, true);
		if (decodeFromString.length / 1024 > size) {
			ContextLog.error("base64图片超出大小限制,base64:" +" 限制大小:"+size, null);
			throw new CheckException("图片过大");
		}
		return decodeFromString;
	}
	
}

其中的ContextLog和CheckException为自定义的打印日志的和全局异常文件,可以忽略替换为自己的即可。

可以看出来,数据的上传和下载都是基于文件流的传输,可以根据需要合理的处理文件流达到自己的目的即可。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐