一、前提准备
1、首先注册一个阿里云账号并实名认证(可直接使用支付宝登录)
2、开通 阿里云 对象存储服务(这里我只做测试使用,所以开通了一个最便宜的1元一月)
3、开通后进入对象存储OSS管理控制台,界面如下
4、创建一个存储空间
根据需求选择创建,一般选择标准存储
创建过后,上传下载需要的你的buketName 和EndPoint;
二、Java操作
这里我用的是Springboot
1、引入阿里提供的依赖
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.8.0</version> </dependency>
我的项目完整依赖如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="#34; xmlns:xsi="#34; xsi:schemaLocation=" #34;> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ali.sso</groupId> <artifactId>upload</artifactId> <version>0.0.1-SNAPSHOT</version> <name>upload</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.1.0</version> </dependency> <!-- --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> <scope>provided</scope> </dependency> <!-- --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <!-- --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.ali.sso</groupId> <artifactId>upload</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2、创建工具类OssUtils
1>一般相对固定的参数
/**
* endpoint是访问OSS的域名。如果您已经在OSS的控制台上 创建了 Bucket ,请在控制台上查看域名。
* 如果您还没有创建Bucket,endpoint选择请参看文档中心的“开发人员指南 > 基本概念 > 访问域名”,
* 链接地址是:
* endpoint的格式形如“”,注意http://后不带bucket名称,
* 比如“”,是错误的endpoint,请去掉其中的“bucket-name”。*/ private static String endpoint = "#34;;
/**
* accessKeyId和accessKeySecret是OSS的访问密钥,您可以在控制台上创建和查看,
* 创建和查看访问密钥的链接地址是:#/。
* 注意:accessKeyId和accessKeySecret前后都没有空格,从控制台复制时请检查并去除多余的空格。
*/
private static String accessKeyId = "*******your accessKeyId******";
private static String accessKeySecret = "******your accessKeySecret********";
/**
* Bucket用来管理所存储Object的存储空间,详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
* Bucket命名规范如下:只能包括小写字母,数字和短横线(-),必须以小写字母或者数字开头,长度必须在3-63字节之间。
*//**
* 就是开始你创建的那个存储空间的名称
*/ private static String bucketName = "your buketName";
/**
* Object是OSS存储数据的基本单元,称为OSS的对象,也被称为OSS的文件。详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
* Object命名规范如下:使用UTF-8编码,长度必须在1-1023字节之间,不能以“/”或者“”字符开头。
*/ private static String firstKey = "my-first-key";
/**
* 图片访问链接的过期时间;上传成功后 获得访问的图片地址时使用
*/
private static final long IMAGE_EXPIRE_TIME = 10 * 365 * 24 * 60 * 60 * 1000L;
2>上传
这里我接收的参数是 MultipartFile,如果是File也可以 具体请参照官方文档
/**
* 文件上传
* @param fileupload
* @return
*/ public static String MultipartFileUpload(MultipartFile fileupload) {
/**
* 创建OSSClient实例
*/ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
String fileName = fileupload.getName();
Long fileSize = fileupload.getSize();
/**
* 创建上传Object的Metadata
*/ ObjectMetadata metadata = new ObjectMetadata();
metadata.setCacheControl("no-cache");
metadata.setHeader("Pragma", "no-cache");
metadata.setContentEncoding("utf-8");
metadata.setContentType(getContentType(fileName));
metadata.setContentDisposition("filename/filesize=" + file Name + "/" + fileSize + "Byte.");
/**
* 文件名格式
*/ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
/**
* 该桶中的文件key
*/ String dateString = sdf.format(new Date()) + fileName;
try {
/**
* 上传文件
*/ ossClient.putObject(bucketName, "img/" + dateString, new ByteArrayInputStream(fileupload.getBytes()), metadata);
} catch (IOException e) {
ossClient.shutdown();
e.printStackTrace();
log.error("文件上传失败[{}]", e.getMessage(), e);
}
/**
* 设置URL过期时间为100年,默认这里是int型,转换为long型即可
*/ Date expiration = new Date(System.currentTimeMillis()+ 3600L * 1000 * 24 * 365 * 100);
/**
* 上传成功生成的URL img中直接赋予src
*/ URL url = ossClient.generatePresignedUrl(bucketName, "img/" + dateString, expiration);
ossClient.shutdown();
return url.toString();
}
拿到上传成功后的url可以直接放在img src中回显
上传图片用到的判断文件格式类型方法
/**
* 通过文件名判断并获取OSS服务文件上传时文件的contentType
*
* @param fileName 文件名
*
* @return 文件的contentType
*/ public static final String getContentType(String fileName) {
String fileExtension = fileName.substring(fileName.lastIndexOf("."));
if (".bmp".equalsIgnoreCase(fileExtension))
return "image/bmp";
if (".gif".equalsIgnoreCase(fileExtension))
return "image/gif";
if (". jpeg ".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension) || ".png".equalsIgnoreCase(fileExtension))
return "image/jpeg";
if (".html".equalsIgnoreCase(fileExtension))
return "text/html";
if (".txt".equalsIgnoreCase(fileExtension))
return "text/plain";
if (".vsd".equalsIgnoreCase(fileExtension))
return "application/vnd.visio";
if (".ppt".equalsIgnoreCase(fileExtension) || ".pptx".equalsIgnoreCase(fileExtension))
return "application/vnd.ms-powerpoint";
if (".doc".equalsIgnoreCase(fileExtension) || ".docx".equalsIgnoreCase(fileExtension))
return "application/msword";
if (".xml".equalsIgnoreCase(fileExtension))
return "text/xml";
return "image/jpeg";
}
将file转换成MultipartFile
File file = new File("/Users/szz/pic/WechatIMG24.jpg");
MultipartFile multipartFile = new CommonsMultipartFile(createFileItem(file,file.getName()));
/*
创建FileItem
*/ public static FileItem createFileItem(File file, String fieldName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem item = factory.createItem(fieldName, getContentType(fieldName), true, file.getName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
try {
FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os. close ();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
3>下载到本地
/** * 下载到本地 * @param objectName 上传到oss的目录加地址 * @param localFile 保存地址 */ public static void downLoadFile(String objectName,String localFile) { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。 ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFile)); // 关闭OSSClient。 ossClient.shutdown(); }
流式下载
/** * 流式下载 * @param objectName */ public static void download(String objectName){ // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。 OSSObject ossObject = ossClient.getObject(bucketName, objectName); // 读取文件内容。 System.out.println("Object content:"); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); while (true) { String line = null; try { line = reader.readLine(); } catch (IOException e) { e.printStackTrace(); } if (line == null) break; System.out.println("n" + line); } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 try { reader.close(); } catch (IOException e) { e.printStackTrace(); } // 关闭OSSClient。 ossClient.shutdown(); }
4、删除文件
/** * * @Title: deleteObject * @Description: 删除文件 * @param @param filePath 文件路径 * @return void 返回类型 * @throws */ public static void deleteObject(String filePath) { OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); ossClient.deleteObject(bucketName, filePath); ossClient.shutdown(); }
三、全部代码
package com.ali.sso.upload.util; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.ObjectMetadata; import lombok.extern.slf4j.Slf4j; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile; import java.io.*; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; /** * @program upload * @description: 阿里云存储OSS * @author: szz * @create: 2019/12/13 10:21 */@Slf4j public class OssUtils { /** * endpoint是访问OSS的域名。如果您已经在OSS的控制台上 创建了Bucket,请在控制台上查看域名。 * 如果您还没有创建Bucket,endpoint选择请参看文档中心的“开发人员指南 > 基本概念 > 访问域名”, * 链接地址是: * endpoint的格式形如“”,注意http://后不带bucket名称, * 比如“”,是错误的endpoint,请去掉其中的“bucket-name”。*/ private static String endpoint = "#34;; /** * accessKeyId和accessKeySecret是OSS的访问密钥,您可以在控制台上创建和查看, * 创建和查看访问密钥的链接地址是:#/。 * 注意:accessKeyId和accessKeySecret前后都没有空格,从控制台复制时请检查并去除多余的空格。 */ private static String accessKeyId = "LTAIZJmPK3qVk2TR"; private static String accessKeySecret = "dDcats6LlPicAvYDswvtv3QHrp3PHT"; /** * Bucket用来管理所存储Object的存储空间,详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。 * Bucket命名规范如下:只能包括小写字母,数字和短横线(-),必须以小写字母或者数字开头,长度必须在3-63字节之间。 */ private static String bucketName = "buket-test1"; /** * Object是OSS存储数据的基本单元,称为OSS的对象,也被称为OSS的文件。详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。 * Object命名规范如下:使用UTF-8编码,长度必须在1-1023字节之间,不能以“/”或者“”字符开头。 */ private static String firstKey = "my-first-key"; /** * 图片访问链接的过期时间 */ private static final long IMAGE_EXPIRE_TIME = 10 * 365 * 24 * 60 * 60 * 1000L; public static void main(String[] args) { File file = new File("/Users/szz/pic/WechatIMG24.jpg"); MultipartFile multipartFile = new CommonsMultipartFile(createFileItem(file,file.getName())); String url = MultipartFileUpload(multipartFile); System.out.println("url:"+url); // deleteObject("img/20191212023137WechatIMG12.jpeg"); // downLoadFile("img/20191212050003WechatIMG12.jpeg","/Users/szz/20191212050003WechatIMG12.jpeg"); // download("img/20191212023137WechatIMG12.jpeg"); } /* 创建FileItem */ public static FileItem createFileItem(File file, String fieldName) { FileItemFactory factory = new DiskFileItemFactory(16, null); FileItem item = factory.createItem(fieldName, getContentType(fieldName), true, file.getName()); int bytesRead = 0; byte[] buffer = new byte[8192]; try { FileInputStream fis = new FileInputStream(file); OutputStream os = item.getOutputStream(); while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } return item; } /** * 文件上传 * @param fileupload * @return */ public static String MultipartFileUpload(MultipartFile fileupload) { /** * 创建OSSClient实例 */ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); String fileName = fileupload.getName(); Long fileSize = fileupload.getSize(); /** * 创建上传Object的Metadata */ ObjectMetadata metadata = new ObjectMetadata(); metadata.setCacheControl("no-cache"); metadata.setHeader("Pragma", "no-cache"); metadata.setContentEncoding("utf-8"); metadata.setContentType(getContentType(fileName)); metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte."); /** * 文件名格式 */ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss"); /** * 该桶中的文件key */ String dateString = sdf.format(new Date()) + fileName;// 20180322010634.jpg try { /** * 上传文件 */ ossClient.putObject(bucketName, "img/" + dateString, new ByteArrayInputStream(fileupload.getBytes()), metadata); } catch (IOException e) { ossClient.shutdown(); e.printStackTrace(); log.error("文件上传失败[{}]", e.getMessage(), e); } /** * 设置URL过期时间为100年,默认这里是int型,转换为long型即可 */ Date expiration = new Date(System.currentTimeMillis()+ 3600L * 1000 * 24 * 365 * 100); /** * 上传成功生成的URL img中直接赋予src */ URL url = ossClient.generatePresignedUrl(bucketName, "img/" + dateString, expiration); ossClient.shutdown(); return url.toString(); } /** * * @Title: deleteObject * @Description: 删除文件 * @param @param filePath 文件路径 * @return void 返回类型 * @throws */ public static void deleteObject(String filePath) { OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); ossClient.deleteObject(bucketName, filePath); ossClient.shutdown(); } /** * 下载到本地 * @param objectName 上传到oss的目录加地址 * @param localFile 保存地址 */ public static void downLoadFile(String objectName,String localFile) { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。 ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFile)); // 关闭OSSClient。 ossClient.shutdown(); } /** * 流式下载 * @param objectName */ public static void download(String objectName){ // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。 OSSObject ossObject = ossClient.getObject(bucketName, objectName); // 读取文件内容。 System.out.println("Object content:"); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); while (true) { String line = null; try { line = reader.readLine(); } catch (IOException e) { e.printStackTrace(); } if (line == null) break; System.out.println("n" + line); } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 try { reader.close(); } catch (IOException e) { e.printStackTrace(); } // 关闭OSSClient。 ossClient.shutdown(); } /** * 通过文件名判断并获取OSS服务文件上传时文件的contentType * * @param fileName 文件名 * * @return 文件的contentType */ public static final String getContentType(String fileName) { String fileExtension = fileName.substring(fileName.lastIndexOf(".")); if (".bmp".equalsIgnoreCase(fileExtension)) return "image/bmp"; if (".gif".equalsIgnoreCase(fileExtension)) return "image/gif"; if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension) || ".png".equalsIgnoreCase(fileExtension)) return "image/jpeg"; if (".html".equalsIgnoreCase(fileExtension)) return "text/html"; if (".txt".equalsIgnoreCase(fileExtension)) return "text/plain"; if (".vsd".equalsIgnoreCase(fileExtension)) return "application/vnd.visio"; if (".ppt".equalsIgnoreCase(fileExtension) || ".pptx".equalsIgnoreCase(fileExtension)) return "application/vnd.ms-powerpoint"; if (".doc".equalsIgnoreCase(fileExtension) || ".docx".equalsIgnoreCase(fileExtension)) return "application/msword"; if (".xml".equalsIgnoreCase(fileExtension)) return "text/xml"; return "image/jpeg"; } }
官方提供了相对比较完整的文档api和SDK,具体可以参照官方文档操作。