阿里云图片/文本存储
一、Springboot中代码实现
官方文档:阿里云oss官网
1、pom.xml中引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
2、AliyunCloudBucket.java 工具类,阿里云对象存储工具类
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.UUID;
/**
* 阿里云对象存储工具类
*/
public class AliyunCloudBucket {
private static final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";//Endpoint以杭州为例
//APPID 和 APP_Secret去阿里云控制台创建即可
private static final String accessKeyId = "APPID";
private static final String accessKeySecret = "APP_Secret";
private static OSS ossClient;
//返回url地址
private static final String https = "https://";
private static final String suffixUrl = ".oss-cn-hangzhou.aliyuncs.com/";
private static final String bucket = "xiaofu-bucket"; //需要创建的桶名称
/**
* 创建 oss 客户端
*/
public static synchronized OSS createOssClient(){
if (ossClient == null){
ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
return ossClient;
}
/**
* 关闭oss客户端
*/
public static void closeOssClient(){
createOssClient().shutdown();
}
/**
* 创建bucket
* Bucket 命名规范:1)只能包括小写字母,数字和短横线(-)
* 2)必须以小写字母或者数字开头
* 3)长度必须在 3-63 字节之间
* eg: String bucketName = "xiaofu-bucket";
*/
public static void createBucket (String bucketName){
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
// 设置存储空间的权限为公共读,默认是私有。
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
createOssClient().createBucket(createBucketRequest);//创建存储空间
closeOssClient();// 关闭OSSClient。
}
/**
* 删除bucket(存储空间)
* 如果不清空bucket里面的存储内容(如图片),会报错
* Exception in thread "main" com.aliyun.oss.OSSException: The bucket you tried to delete is not empty.
* @param bucketName
*/
public static void deleteBucket(String bucketName){
createOssClient().deleteBucket(bucketName);
closeOssClient(); // 关闭OSSClient
}
/**
* 上传对象:MultipartFile 前端传递的文件格式为form-data
* 上传对象公共读的url格式:
https://xiaofu-bucket.oss-cn-hangzhou.aliyuncs.com/1.jpg
* @param multipartFile
* @throws IOException
*/
public static String uploadMultipartFile(MultipartFile multipartFile) throws IOException {
//创建文件对象
File file = multipartFileToFile(multipartFile);
// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
String key = UUID.randomUUID() + multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
createOssClient().putObject(bucket,key,file);
// 关闭OSSClient。
closeOssClient();
return https + bucket + suffixUrl + key;
}
/**
* 上传base64文件图片,将base64转换成MultipartFile
* @param image
* @return
* @throws IOException
*/
public static String uploadBase64Image(String image) throws IOException {
BASE64DecodedMultipartFile base64DecodedMultipartFile = null;
if(null != image && !image.isEmpty()){
base64DecodedMultipartFile = (BASE64DecodedMultipartFile) Base64StrToImage.base64MutipartFile(image);
}
//调用上传MultipartFile方法
return uploadMultipartFile(base64DecodedMultipartFile);
}
/**
* multipartFileToFile
* @param multipartFile
* @return
* @throws IOException
*/
public static File multipartFileToFile(MultipartFile multipartFile) throws IOException {
// 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称
File file = File.createTempFile(
multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")+1),
null);
// MultipartFile 转成 file
multipartFile.transferTo(file);
//在虚拟机终止时,请求删除此抽象路径名表示的文件或目录
file.deleteOnExit();
return file;
}
/**
* 下载对象
* ObjectName从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
* @throws IOException
*/
public static void download(String objectName) throws IOException {
String bucketName = "xiaofu-bucket";
// 调用ossClient.getObject返回一个OSSObject实例,该实例包含文件内容及文件元信息。
OSSObject ossObject = createOssClient().getObject(bucketName, objectName);
// 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。
InputStream content = ossObject.getObjectContent();
if (content != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
while (true) {
String line = reader.readLine();
if (line == null) break;
System.out.println("\n" + line);
}
// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
content.close();
}
closeOssClient();// 关闭OSSClient。
}
/**
* 删除对象
* ObjectName表示删除OSS文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
*/
public static void delete(String picUrl){
String condition = "aliyuncs.com/";
String objectUrl = picUrl.substring(picUrl.lastIndexOf(condition)+condition.length());
createOssClient().deleteObject(bucket, objectUrl);
closeOssClient(); // 关闭OSSClient。
}
}
3、BASE64DecodedMultipartFile.java工具类, MultipartFile的实现类
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
* MultipartFile的实现类
*/
public class BASE64DecodedMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
return System.currentTimeMillis() + (int)Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
return header.split(":")[1];
}
@Override
public boolean isEmpty() {
return imgContent == null || imgContent.length ==0;
}
@Override
public long getSize() {
return imgContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return imgContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(imgContent);
}
@Override
public void transferTo(File file) throws IOException, IllegalStateException {
new FileOutputStream(file).write(imgContent);
}
}
4、Base64StrToImage.java 工具类,将接收到的base64格式值进行解码
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
/**
* 将接收到的base64格式值进行解码
*/
public class Base64StrToImage {
public static MultipartFile base64MutipartFile(String imgStr){
try {
String [] baseStr = imgStr.split(",");
BASE64Decoder base64Decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = base64Decoder.decodeBuffer(baseStr[1]);
for(int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new BASE64DecodedMultipartFile(b,baseStr[0]) ;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
5、Controller层
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@RestController
public class AliyunBucketController {
/**
* 上传图片 : 前端格式为form-data,后端用MultipartFile接收
* @param file
* @return
*/
@RequestMapping("aliUpload")
public Object upload(MultipartFile file){
String url = null;
try {
url = AliyunCloudBucket.uploadMultipartFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return url;
}
/**
* 上传base64:前端传递base64文件
* @param image
* @return
*/
@RequestMapping("/base64")
public Object uploadBase64(@RequestBody String image){
String url = null;
try {
url = AliyunCloudBucket.uploadBase64Image(image);
} catch (IOException e) {
e.printStackTrace();
}
return url;
}
}
二、postman调试
1、form-data格式
2、base64格式