您的位置 首页 java

Java使用阿里云对象存储OSS实现图片上传下载

一、前提准备

1、首先注册一个阿里云账号并实名认证(可直接使用支付宝登录)

2、开通 阿里云 对象存储服务(这里我只做测试使用,所以开通了一个最便宜的1元一月)

3、开通后进入对象存储OSS管理控制台,界面如下

Java使用阿里云对象存储OSS实现图片上传下载

4、创建一个存储空间

Java使用阿里云对象存储OSS实现图片上传下载

根据需求选择创建,一般选择标准存储

创建过后,上传下载需要的你的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,具体可以参照官方文档操作。

文章来源:智云一二三科技

文章标题:Java使用阿里云对象存储OSS实现图片上传下载

文章地址:https://www.zhihuclub.com/178238.shtml

关于作者: 智云科技

热门文章

网站地图