购买资源包,可按年按月付费,也可按照流量计费。根据自己需要购买。
存储类型:
标准存储:高可用、高性能的,基本的数据访问,用于正常网站访问,保证数据量大的网站读写能力。
低频访问存储:一般用于上传的东西很少有人访问,用于自己的数据存储和学习,收费低于标准存储
归档存储:用于数据归档,基本出问题才需要去查看的数据,收费低于低频访问存储。
冷归档存储:用于数据归档,基本不访问,收费低于归档存储。
读写权限选择公共读:写入需要配置参数进行授权写入,上传的资源,所有人都能通过链接访问。
存储路径(FOLDER)
秘钥(ACCESS_KEY_ID、ACCESS_KEY_SECRET)--老版本
Bucket名称(BACKET_NAME)
外网域名
<!-- 阿里云oss --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.0.0</version> </dependency>
package com.central.file.config.aliyun;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.central.common.utils.DateUtils;
import com.central.file.utils.UUIDUtils;
import com.sun.deploy.net.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author sang
* @class:AliyunOSSClientUtil
* @descript:java使用阿里云OSS存储对象上传图片
* @date:2022年3月16日 下午5:58:08
*/
public class AliyunOSSClientUtil{
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
private long bytesWritten = 0;
private long totalBytes = -1;
private boolean succeed = false;
private static String number;
//阿里云API的内或外网域名
private static String ENDPOINT;
//阿里云API的密钥Access Key ID
private static String ACCESS_KEY_ID;
//阿里云API的密钥Access Key Secret
private static String ACCESS_KEY_SECRET;
//阿里云API的bucket名称
private static String BACKET_NAME;
//阿里云API的文件夹名称
private static String FOLDER;
//初始化
/* private static OSSClient ossClient=AliyunOSSClientUtil.getOSSClient();*/
//初始化属性
static {
ENDPOINT = OSSClientConstants.ENDPOINT;
ACCESS_KEY_ID = OSSClientConstants.ACCESS_KEY_ID;
ACCESS_KEY_SECRET = OSSClientConstants.ACCESS_KEY_SECRET;
BACKET_NAME = OSSClientConstants.BACKET_NAME;
FOLDER = OSSClientConstants.FOLDER;
}
/**
* 获取阿里云OSS客户端对象
*
* @return ossClient
*/
public static OSSClient getOSSClient() {
ClientBuilderConfiguration conf = new ClientBuilderConfiguration(); // 连接空闲超时时间,超时则关闭
conf.setIdleConnectionTime(1000); // 在这里可以做一些配置,比如超时时间、最大连
return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
}
/**
* 创建存储空间
*
* @param ossClient OSS连接
* @param bucketName 存储空间
* @return
*/
public static String createBucketName(OSSClient ossClient, String bucketName) {
//存储空间
final String bucketNames = bucketName;
if (!ossClient.doesBucketExist(bucketName)) {
//创建存储空间
Bucket bucket = ossClient.createBucket(bucketName);
log.info("创建存储空间成功");
return bucket.getName();
}
return bucketNames;
}
/**
* 删除存储空间buckName
*
* @param ossClient oss对象
* @param bucketName 存储空间
*/
public static void deleteBucket(OSSClient ossClient, String bucketName) {
ossClient.deleteBucket(bucketName);
log.info("删除" + bucketName + "Bucket成功");
}
/**
* 创建模拟文件夹
*
* @param ossClient oss连接
* @param bucketName 存储空间
* @param folder 模拟文件夹名如"qj_nanjing/"
* @return 文件夹名
*/
public static String createFolder(OSSClient ossClient, String bucketName, String folder) {
//文件夹名
final String keySuffixWithSlash = folder;
//判断文件夹是否存在,不存在则创建
if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
//创建文件夹
ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
log.info("创建文件夹成功");
//得到文件夹名
OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
String fileDir = object.getKey();
return fileDir;
}
return keySuffixWithSlash;
}
/**
* 根据key删除OSS服务器上的文件
*
* @param ossClient oss连接
* @param bucketName 存储空间
* @param folder 模拟文件夹名 如"qj_nanjing/"
* @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
*/
public static void deleteFile(OSSClient ossClient, String bucketName, String folder, String key) {
ossClient.deleteObject(bucketName, folder + key);
log.info("删除" + bucketName + "下的文件" + folder + key + "成功");
}
//测试
public void main(String[] args) {
//初始化OSSClient
OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
//上传文件
String imgPath = "C:\\Users\\yaya\\Pictures\\内控项目图片\\yuan.png";
String[] file = imgPath.split(",");
for (String filename : file) {
//System.out.println("filename:"+filename);
File filess = new File(filename);
String md5key = this.uploadObject2OSS(ossClient, filess, BACKET_NAME, FOLDER).get("resultStr").toString();
log.info("上传后的文件MD5数字唯一签名:" + md5key);
//上传后的文件MD5数字唯一签名:40F4131427068E08451D37F02021473A
}
}
/**
* 上传图片至OSS
*
* @param ossClient oss连接
* @param file 上传文件(文件全路径如:D:\\image\\cake.jpg)
* @param bucketName 存储空间
* @param folder 模拟文件夹名 如"qj_nanjing/"
* @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
*/
public Map<String, Object> uploadObject2OSS(OSSClient ossClient, File file, String bucketName, String folder) {
String resultStr = null;
Map map = new HashMap();
try {
//以输入流的形式上传文件
InputStream is = new FileInputStream(file);
//文件名
String fileName = file.getName();
fileName.replace("/", "").replace("\\", "");
fileName = fileName.substring(0, fileName.lastIndexOf("."))
+ UUIDUtils.getUUID() + fileName.substring(fileName.lastIndexOf("."));
// key的组成
/*String newFileName= UUID.randomUUID().toString();*/
//文件大小
Long fileSize = file.length();
//创建上传Object的Metadata
ObjectMetadata metadata = new ObjectMetadata();
//上传的文件的长度
metadata.setContentLength(is.available());
//指定该Object被下载时的网页的缓存行为
metadata.setCacheControl("no-cache");
//指定该Object下设置Header
metadata.setHeader("Pragma", "no-cache");
//指定该Object被下载时的内容编码格式
metadata.setContentEncoding("utf-8");
//文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
//如果没有扩展名则填默认值application/octet-stream
metadata.setContentType(this.getContentType(fileName));
//指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
//上传文件 (上传文件流的形式)
PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
//解析结果
System.out.println(this.getUrl(fileName));
resultStr = putResult.getETag();
map.put("resultStr", resultStr);
map.put("imageUrl", fileName);
} catch (Exception e) {
e.printStackTrace();
log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
}
return map;
}
/**
* 通过文件名判断并获取OSS服务文件上传时文件的contentType
*
* @param fileName 文件名
* @return 文件的contentType
*/
public 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";
}
if (".flv".equalsIgnoreCase(fileExtension)) {
return "video/x-flv";
}
if (".mp3".equalsIgnoreCase(fileExtension)) {
return "audio/mpeg";
}
if (".mp4".equalsIgnoreCase(fileExtension)) {
return "video/mp4";
}
//默认返回类型
return "image/jpeg";
}
//通过key获取到上传文件的地址
public String getUrl(String key) {
OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
// 设置URL过期时间为10年 3600l* 1000*24*365*10
Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);
// 生成URL
URL url = ossClient.generatePresignedUrl(BACKET_NAME, key, expiration);
if (url != null) {
return url.toString().split("\\?")[0];
}
return null;
}
/**
* 上传图片至OSS
*
* @param ossClient oss连接
* @param (文件全路径如:D:\\image\\cake.jpg)
* @param bucketName 存储空间
* @param folder 模拟文件夹名 如"qj_nanjing/"
* @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
*/
public Map<String, Object> uploadObject2OSSnew(OSSClient ossClient, MultipartFile f, String bucketName, String folder, String bisType,String sessionKey) {
number = sessionKey;
String resultStr = null;
Map map = new HashMap();
try {
//以输入流的形式上传文件
InputStream is = f.getInputStream();
//文件名
String fileName = f.getOriginalFilename();
if (fileName.lastIndexOf(".") == -1) {
fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + Calendar.getInstance().getTimeInMillis() + ".jpg";
}
fileName.replace("/", "").replace("\\", "");
if ("".equals(fileName)) {
fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + ".jpg";
} else {
fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + fileName.substring(fileName.lastIndexOf("."), fileName.length());
}
if (StringUtils.isNotEmpty(bisType)) {
fileName = bisType + "/" + fileName;
}
if(StringUtils.isNotEmpty(folder)){
fileName = folder + "/" + fileName;
}
// key的组成
/*String newFileName= UUID.randomUUID().toString();*/
//文件大小
Long fileSize = f.getSize();
//创建上传Object的Metadata
ObjectMetadata metadata = new ObjectMetadata();
//上传的文件的长度
metadata.setContentLength(is.available());
//指定该Object被下载时的网页的缓存行为
metadata.setCacheControl("no-cache");
//指定该Object下设置Header
metadata.setHeader("Pragma", "no-cache");
//指定该Object被下载时的内容编码格式
metadata.setContentEncoding("utf-8");
//文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
//如果没有扩展名则填默认值application/octet-stream
metadata.setContentType(f.getContentType());
//指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
//上传文件 (上传文件流的形式)
PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
// 带进度条的上传。
//解析结果
System.out.println(getUrl(fileName));
resultStr = putResult.getETag();
map.put("resultStr", resultStr);
map.put("guid", fileName);
map.put("imageUrl", getUrl(fileName));
System.out.println(map);
// 关闭OSSClient。
ossClient.shutdown();
} catch (Exception e) {
e.printStackTrace();
log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
}
return map;
}
//上传返回url
public String getFileUrl(File file) {
//上传图片 file 文件 folder 文件夹名字
OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
Map map = uploadObject2OSS(ossClient, file, BACKET_NAME, FOLDER);
return this.getUrl(map.get("imageUrl").toString());
}
public String getFileUrlNew(MultipartFile m, String bisType,String sessionKey) {
OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,sessionKey);
return map.get("imageUrl").toString();
}
public Map<String, String> getFileUrlNewFlow(MultipartFile m, String bisType) {
OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,"");
return map;
}
}
package com.central.file.config;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.central.file.model.FileInfo;
import com.central.file.properties.FileServerProperties;
import com.central.file.service.impl.AbstractIFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.aliyun.oss.OSSClient;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* 阿里云配置
*
* @author koko
*/
@Configuration
@ConditionalOnProperty(name = "cgs.file-server.type", havingValue = "aliyun")
public class AliyunOSSAutoConfigure {
@Autowired
private FileServerProperties fileProperties;
/**
* 阿里云文件存储client
* 只有配置了aliyun.oss.access-key才可以使用
*/
@Bean
public OSSClient ossClient() {
OSSClient ossClient = new OSSClient(fileProperties.getOss().getEndpoint()
, new DefaultCredentialProvider(fileProperties.getOss().getAccessKey(), fileProperties.getOss().getAccessKeySecret())
, null);
return ossClient;
}
@Service
public class AliyunOssServiceImpl extends AbstractIFileService {
@Autowired
private OSSClient ossClient;
@Override
protected String fileType() {
return fileProperties.getType();
}
@Override
protected void uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception {
ossClient.putObject(fileProperties.getOss().getBucketName(), fileInfo.getName(), file.getInputStream());
fileInfo.setUrl(fileProperties.getOss().getDomain() + "/" + fileInfo.getName());
}
@Override
protected boolean deleteFile(FileInfo fileInfo) {
ossClient.deleteObject(fileProperties.getOss().getBucketName(), fileInfo.getName());
return true;
}
}
}
阿里云上传接口访问(uploadImg)
package com.central.file.controller;
import com.central.common.model.PageResult;
import com.central.common.model.Result;
import com.central.common.utils.DateUtils;
import com.central.file.config.aliyun.AliyunOSSClientUtil;
import com.central.file.config.qiniu.UtilsUpload;
import com.central.file.model.FileInfo;
import com.central.file.model.ReturnMovo;
import com.central.file.service.IFileService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 文件上传
*
* @author koko
*/
@Log4j2
@Controller
@RequestMapping("/aliyunFile")
@CrossOrigin
public class AliyunFileController {
@Resource
private IFileService fileService;
@Autowired
private Environment environment;
/*@Resource
private UserService userService;*/
/**
* 文件上传
* 根据fileType选择上传方式
*
* @param file
* @return
* @throws Exception
*/
@PostMapping("/files-anon")
public FileInfo upload(@RequestParam("file") MultipartFile file) throws Exception {
return fileService.upload(file);
}
/***
* 阿里云上传图片
*/
@RequestMapping("uploadImg")
@ResponseBody
public FileInfo uploadImg(@RequestParam MultipartFile file) {
FileInfo resultModel = new FileInfo();
Map<String, Object> map = new HashMap<>();
try {
if (!file.isEmpty()) {
String avatar = new AliyunOSSClientUtil().getFileUrlNew(file, "", "");
resultModel.setStatus(0);
resultModel.setMsg("保存成功");
resultModel.setPath(avatar);
return resultModel;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// /**
// * 上传文件
// */
// @PostMapping("/updateFile")
// @ResponseBody
// public FileInfo updateFile(@RequestParam("file") MultipartFile file) {
// FileInfo fileInfo = new FileInfo();
//
// try {
// if (!file.isEmpty()) {
// String url = UtilsUpload.uploadImgByMultipartFile(file,false);
// fileInfo.setUrl(url);
// }
// } catch (Exception e) {
// fileInfo.setStatus(1);
// fileInfo.setMsg("文件上传失败");
// }
// return fileInfo;
// }
/**
* 上传文件
*/
@PostMapping("/updateFile")
@ResponseBody
public FileInfo uploadFile(@RequestParam("file") MultipartFile file){
FileInfo fileInfo = new FileInfo();
// 判断文件是否为空
String filePath = "";
String filename = file.getOriginalFilename();
//获取当前时间
String timeStr = DateUtils.YMD.format(new Date());
if (!file.isEmpty()) {
try {
//判断文件目录是否存在,否则自动生成
File directory = new File(environment.getProperty("upload")+timeStr);
if (!directory.exists()){
directory.mkdir();
}
//失败跳转视图
//获取图片扩展名
// String ext = filename.substring(filename.lastIndexOf("."));
// filename = StringUtils.gainGUID() +ext;
// 文件保存路径
filePath = FilenameUtils.concat(environment.getProperty("upload")+timeStr, filename);
// 转存文件
file.transferTo(new File(filePath));
fileInfo.setUrl(environment.getProperty("fileupload.directory")+timeStr+"/"+filename);
} catch (Exception e) {
e.printStackTrace();
fileInfo.setStatus(1);
fileInfo.setMsg("文件上传失败");
}
}
//成功跳转视图
return fileInfo;
}
@PostMapping("/updateFileEdit")
@ResponseBody
public ReturnMovo updateFileEdit(MultipartFile file) {
ReturnMovo returnMovo = new ReturnMovo();
Map<String, Object> map = new HashMap<>();
try {
if (!file.isEmpty()) {
String url = UtilsUpload.uploadImgByMultipartFile(file,false);
map.put("src", url);
returnMovo.setData(map);
}
} catch (Exception e) {
returnMovo.setCode(1);
returnMovo.setMsg("文件上传失败");
}
return returnMovo;
}
/**
* 文件删除
*
* @param id
*/
@DeleteMapping("/files/{id}")
public Result delete(@PathVariable String id) {
try {
fileService.delete(id);
return Result.succeed("操作成功");
} catch (Exception ex) {
return Result.failed("操作失败");
}
}
/**
* 文件查询
*
* @param params
* @return
*/
@GetMapping("/files")
public PageResult<FileInfo> findFiles(@RequestParam Map<String, Object> params) {
return fileService.findList(params);
}
}
前端就不写了,就是一种是单文件上传,另一种多文件上传。控件很多,有空再写。