阿里云oss的使用

1.首先第一步我们需要创建Bucket

阿里云oss的使用

 

2.Bucket和外网oss地址

阿里云oss的使用

 

 

 3.创建AccessKey,建议子账户,但我们不走寻常路,直接就是主账户的

阿里云oss的使用

 

 

 4.这是创建好了的,这个可不能泄露

阿里云oss的使用

 

 

 5.上代码

package com.oss;

import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.IOUtils;


import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;

/**
 * @author 杨小华
 * @desc 阿里文件云存储管理类
 * @create 2017/11/27 14:25
 **/
@Slf4j
public class OSSClientUtil {
// 就是刚刚让你创建的AccessKey
static final String ACCESS_KEY_ID = "这是你的AccessKey ID"; static final String ACCESS_KEY_SECRET = "这是你的AccessKey Secret"; /** * 用户的存储空间(bucket)名称 */ static final String BUCKET_NAME = "bucket名称"; /** * 对应的映射域名 */ private static final String ACCESS_URL = "http://www.baidu.com/"; /** * 用户的存储空间所在数据中心的访问域名 */ private static final String ENDPOINT = "http://oss-cn-chengdu.aliyuncs.com"; /** * 指定项目文件夹 */ private static final String PIC_LOCATION = "gym/"; /** * 加密密钥 */ private static final String KEY = "gym"; private static OSSClient ossClient; /** * @desc 静态初始化ossClient * @author 杨小华 * @create 2017/11/25 12:44 **/ static { ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET); } /** * @desc 上传自定义格式 * @author 杨小华 * @create 2017/11/24 11:09 **/ public static String upload(InputStream is, String directory, String fileType) { String fileName = getFileName() + "." + fileType; return uploadFile(is, directory, fileName); } /** * @desc 上传视频指定mp4格式 * @author 杨小华 * @create 2017/11/22 15:00 **/ public static String uploadVideo(InputStream is, String directory) { String fileName = getFileName() + ".mp4"; return uploadFile(is, directory, fileName); } /** * @desc 上传图片指定png格式 * @author 杨小华 * @create 2017/11/22 14:59 **/ public static String uploadImage(InputStream is, String directory) { String fileName = getFileName() + ".png"; return uploadFile(is, directory, fileName); } /** * @desc 上传网络图片指定png格式 * @author 杨小华 * @create 2017/11/25 13:37 **/ public static String uploadWebImage(String fileUrl, String directory) { String fileName = getFileName() + ".png"; return uploadWebFile(fileUrl, directory, fileName); } /** * @desc 上传本地文件(文件流上传) * @author 杨小华 * @create 2017/11/23 19:57 **/ public static String uploadFile(InputStream is, String directory, String fileName) { String key = PIC_LOCATION + directory + "/" + fileName; if (Objects.isNull(directory)) { key = fileName; } try { ObjectMetadata objectMetadata = getObjectMetadata(is.available()); objectMetadata.setHeader(OSSHeaders.CONTENT_TYPE, "image/png"); ossClient.putObject(BUCKET_NAME, key, is, objectMetadata); } catch (Exception e) { log.error(e.getMessage()); return null; } finally { IOUtils.safeClose(is); } return ACCESS_URL + key; } /** * @desc 上传网络图片 * @author 杨小华 * @create 2017/11/24 15:43 **/ public static String uploadWebFile(String fileUrl, String directory, String fileName) { String key = PIC_LOCATION + directory + "/" + fileName; InputStream is = null; try { Integer length = new URL(fileUrl).openConnection().getContentLength(); is = new URL(fileUrl).openStream(); ObjectMetadata objectMetadata = getObjectMetadata(length); ossClient.putObject(BUCKET_NAME, key, is, objectMetadata); } catch (Exception e) { log.error(e.getMessage()); return null; } finally { IOUtils.safeClose(is); } return ACCESS_URL + key; } /** * @desc 更新文件:只更新内容,不更新文件名和文件地址。 (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意) * @author 杨小华 * @create 2017/11/23 20:40 **/ public static String updateFile(InputStream is, String fileUrl) { String key = getFileNameByUrl(fileUrl); return uploadFile(is, null, key); } /** * @desc 替换文件:删除原文件并上传新文件,文件名和地址同时替换 解决原数据缓存问题,只要更新了地址,就能重新加载数据) * @author 杨小华 * @create 2017/11/24 14:19 **/ public static String replaceFile(InputStream is, String fileUrl) { boolean flag = deleteObject(fileUrl); String fileName = getFileNameByUrl(fileUrl); if (!flag) { return null; } return uploadFile(is, null, fileName); } /** * @desc 查询文件是否存在 * @author 杨小华 * @create 2017/11/24 10:09 **/ public static boolean doesObjectExist(String key) { boolean result = false; try { //如果带http,提取key值 if (key.indexOf("http") != -1) { key = getFileNameByUrl(key); } result = ossClient.doesObjectExist(BUCKET_NAME, key); } catch (Exception e) { log.error(e.getMessage()); } return result; } /** * @desc 删除Object。 注意:以下所有删除如果文件不存在返回的是true,如果需要先判断是否存在先调用doesObjectExist()方法 * @author 杨小华 * @create 2017/11/24 10:06 **/ public static boolean deleteObject(String fileUrl) { try { String key = getFileNameByUrl(fileUrl); ossClient.deleteObject(BUCKET_NAME, key); } catch (Exception e) { log.error(e.getMessage()); return false; } return true; } /** * @desc 批量删除object(适用于相同的endpoint和bucketName) * @author 杨小华 * @create 2017/11/24 10:02 **/ public static int deleteObjects(List<String> fileUrls) { int count = 0; List<String> keys = getFileNamesByUrl(fileUrls); try { // 删除Objects DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(BUCKET_NAME); deleteRequest.withKeys(keys); count = ossClient.deleteObjects(deleteRequest).getDeletedObjects().size(); } catch (Exception e) { log.error(e.getMessage()); } return count; } /** * @desc 批量文件删除(较慢, 适用于不同endpoint和bucketName) * @author 杨小华 * @create 2017/11/24 13:03 **/ public static int deleteBatchObject(List<String> fileUrls) { int count = 0; for (String url : fileUrls) { if (deleteObject(url)) { count++; } } return count; } /** * @desc web直传获取签名 * @author 杨小华 * @create 2017/9/11 13:01 **/ public static Map<String, Object> getWebSign(String callbackUrl, int seconds) { Map<String, Object> data = Maps.newHashMap(); // 存储目录 String dir = PIC_LOCATION + "web/" + getDirectory(); //回调内容 Map<String, String> callback = Maps.newHashMap(); callback.put("callbackUrl", callbackUrl); callback.put("callbackBody", "filename=${object}&size=${size}&mimeType=${mimeType}&height" + "=${imageInfo.height}&width=${imageInfo.width}"); callback.put("callbackBodyType", "application/x-www-form-urlencoded"); //签名有效期30秒过期 Date expiration = DateTime.now().plusSeconds(seconds).toDate(); // 提交节点 String host = "http://" + BUCKET_NAME + "." + ENDPOINT; try { PolicyConditions policyConds = new PolicyConditions(); // 设置上传文件的大小限制 policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); //指定此次上传的文件名必须是dir变量的值开头 policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); //policy String policy = BinaryUtil.toBase64String(postPolicy.getBytes("utf-8")); //签名 String signature = ossClient.calculatePostSignature(postPolicy); //回调 String callbackData = BinaryUtil.toBase64String(callback.toString().getBytes("utf-8")); data.put("policy", policy); data.put("signature", signature); data.put("callback", callbackData); data.put("dir", dir); data.put("accessKeyId", ACCESS_KEY_ID); data.put("accessUrl", ACCESS_URL); data.put("host", host); data.put("expire", expiration); } catch (Exception e) { log.error(e.getMessage(), e); return null; } return data; } /** * 移动端临时授权上传 * * @return java.util.Map<java.lang.String,java.lang.Object> * @author 杨小华 * @date 2018/1/29 14:11 * @since 1.0.0 */ /*public static Map<String, Object> getSTSWrite() { Map<String, Object> data = Maps.newHashMap(); // 设置文件目录 String folder = PIC_LOCATION + "app/" + getDirectory(); //权限验证 AssumeRoleResponse.Credentials credentials = STSUtil.createSTSForPutObject(folder); Preconditions.checkState(Objects.nonNull(credentials), "权限获取失败,请重试"); AssumeRoleResponse.Credentials encryptCredentials = DESUtil.encrypt(credentials, KEY); //完整文件名 data.put("oss", encryptCredentials); data.put("folder", folder); data.put("endpoint", ENDPOINT); data.put("buckName", BUCKET_NAME); data.put("accessUrl", ACCESS_URL); return data; }*/ /** * 移动端临时授权下载 * * @return java.util.Map<java.lang.String,java.lang.Object> * @author 杨小华 * @date 2018/1/31 15:33 * @since 1.0.0 */ /*public static Map<String, Object> getSTSRead() { Map<String, Object> data = Maps.newHashMap(); //权限验证 AssumeRoleResponse.Credentials credentials = STSUtil.createSTSForReadOnly(); Preconditions.checkState(Objects.nonNull(credentials), "权限获取失败,请重试"); AssumeRoleResponse.Credentials encryptCredentials = DESUtil.encrypt(credentials, KEY); //完整文件名 data.put("oss", encryptCredentials); data.put("endpoint", ENDPOINT); data.put("buckName", BUCKET_NAME); return data; }*/ /** * 私有型bucket,生成签名URL * * @param key 表情地址,如face/zip/test.zip * @param seconds 多少秒后过期 * @return java.lang.String * @author 杨小华 * @date 2018/2/2 14:32 * @since 1.0.0 */ public static String getSignUrl(String key, int seconds) { //如果key值不存在 Preconditions.checkArgument(doesObjectExist(key), "key值不存在"); Date expire = DateTime.now().plusSeconds(seconds).toDate(); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(BUCKET_NAME, key); generatePresignedUrlRequest.setExpiration(expire); URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest); return url.toString(); } /** * 单个下载文件 * * @param key 文件key值 * @param fileUrl 目标文件路径名称 * @return boolean * @author 杨小华 * @date 2018/2/2 18:08 * @since 1.0.0 */ public static boolean getObject(String key, String fileUrl) { ObjectMetadata object = ossClient.getObject(new GetObjectRequest(BUCKET_NAME, key), new File(fileUrl)); if (Objects.nonNull(object)) { return true; } return false; } /** * 批量下载文件 * * @param preFix 下载某个文件夹中的所有 * @param dir 目标目录 * @return java.lang.String * @author 杨小华 * @date 2018/2/2 17:33 * @since 1.0.0 */ public static String listObject(String preFix, String dir) { // 构造ListObjectsRequest请求 ListObjectsRequest listObjectsRequest = new ListObjectsRequest(BUCKET_NAME); //Delimiter 设置为 “/” 时,罗列该文件夹下的文件 listObjectsRequest.setDelimiter("/"); //Prefix 设为某个文件夹名,罗列以此 Prefix 开头的文件 listObjectsRequest.setPrefix(preFix); ObjectListing listing = ossClient.listObjects(listObjectsRequest); //如果改目录下没有文件返回null if (CollectionUtils.isEmpty(listing.getObjectSummaries())) { return null; } // 取第一个目录的key File file = new File(dir + listing.getObjectSummaries().get(0).getKey()); //判断文件所在本地路径是否存在,若无,新建目录 File fileParent = file.getParentFile(); if (!fileParent.exists()) { fileParent.mkdirs(); } // 遍历所有Object:目录下的文件 for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) { //Bucket中存储文件的路径 String key = objectSummary.getKey(); //下载object到文件 ossClient.getObject(new GetObjectRequest(BUCKET_NAME, key), file); } return file.getParent(); } /** * @desc 生成文件名 * @author 杨小华 * @create 2017/11/24 11:15 **/ public static String getFileName() { return LocalDateTime.now().toString("yyyyMMddHHmmssSSS_") + RandomStringUtils .randomNumeric(6); } /** * 生成目录 * * @return java.lang.String * @author 杨小华 * @date 2018/1/29 19:00 * @since 1.0.0 */ public static String getDirectory() { return LocalDateTime.now().toString("yyyy-MM-dd"); } /** * @desc 根据url获取fileName * @author 杨小华 * @create 2017/11/23 20:40 **/ private static String getFileNameByUrl(String fileUrl) { int beginIndex = fileUrl.indexOf(ACCESS_URL); //针对单个图片处理的图片 int endIndex = fileUrl.indexOf("?"); //针对使用模板图片处理的图片 int endIndex2 = fileUrl.indexOf("@!"); if (beginIndex == -1) { return null; } if (endIndex != -1) { return fileUrl.substring(beginIndex + ACCESS_URL.length(), endIndex); } if (endIndex2 != -1) { return fileUrl.substring(beginIndex + ACCESS_URL.length(), endIndex2); } return fileUrl.substring(beginIndex + ACCESS_URL.length()); } /** * @desc 根据url获取fileNames集合 * @author 杨小华 * @create 2017/11/23 20:42 **/ private static List<String> getFileNamesByUrl(List<String> fileUrls) { List<String> fileNames = Lists.newArrayList(); for (String url : fileUrls) { fileNames.add(getFileNameByUrl(url)); } return fileNames; } /** * @desc ObjectMetaData是用户对该object的描述, * 由一系列name-value对组成;其中ContentLength是必须设置的,以便SDK可以正确识别上传Object的大小 * @author 杨小华 * @create 2017/11/23 20:12 **/ private static ObjectMetadata getObjectMetadata(long length) { ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentLength(length); // 被下载时网页的缓存行为 objectMetadata.setCacheControl("no-cache"); objectMetadata.setHeader("Pragma", "no-cache"); return objectMetadata; } public static void main(String[] args) throws FileNotFoundException { File file = new File("C:\\Users\\qian\\Desktop\\Snipaste_2021-06-29_14-28-06.png"); InputStream is = new FileInputStream(file); String result = OSSClientUtil.uploadImage(is, "data"); System.out.println(result); } }

6.上传后的访问地址是Bucket + oss外网地址 + 路径才能访问的

(1)那么地址就是:http://2222oos.oss-cn-chengdu.aliyuncs.com/gym/data/20210706162051487_104064.png

   但是呢这个地址你直接访问是访问不了的,需要开启授权

 阿里云oss的使用

 

 

 7.授权开启方法(该目录的整个访问权限就是/*)

阿里云oss的使用

 

 

 

 阿里云oss的使用

 

 

 

 8.现在就能访问到了(但是新问题来了)

  图片是直接下载下来的,而不是预览,所以我们就要解决这个问题,

  代码部分需要设置响应头,代码里已经设置好了的

阿里云oss的使用

 阿里云oss的使用

9.需要绑定域名,具体请看如下教程

https://help.aliyun.com/document_detail/31902.htm?spm=a2c4g.11186623.2.2.552014fa0eY2LT#concept-ozw-m2r-5fb

10.把代码中的ACCESS_URL替换成的域名即可,这下就可以预览了

阿里云oss的使用

 

阿里云oss的使用

上一篇:C# 限制窗体弹窗显示必须关闭后才能重新实例化窗体


下一篇:逻辑是怎样炼成的?