开启对象存储服务后(按流量计费),进入对象存储控制台
创建Bucket
点击头像, 进入Accesskey管理
创建AccessKey
至此得到信息
bucket:gulimall-oss123
endpoint:oss-cn-hangzhou.aliyuncs.com
url:gulimall-oss123.oss-cn-hangzhou.aliyuncs.com
AccessKey ID:LTAI5tS2xGi7WUz7GbaVnK2z
AccessKey Secret:l5VQHnGdmNLXXPyDTGinhWN8SSMYEU
阿里云对象存储官方文档
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alicloud-ossartifactId>
dependency>
application.properties
#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId=LTAI5tS2xGi7WUz7GbaVnK2z
aliyun.oss.secret=l5VQHnGdmNLXXPyDTGinhWN8SSMYEU
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.bucket=gulimall-oss123
ConstantOssPropertiesUtils
package com.atguigu.gulimall.mytest.utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ConstantOssPropertiesUtils implements InitializingBean {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.oss.secret}")
private String secret;
@Value("${aliyun.oss.bucket}")
private String bucket;
public static String EDNPOINT;
public static String ACCESS_KEY_ID;
public static String SECRECT;
public static String BUCKET;
@Override
public void afterPropertiesSet() throws Exception {
EDNPOINT=endpoint;
ACCESS_KEY_ID=accessKeyId;
SECRECT=secret;
BUCKET=bucket;
}
}
这种上传方式需要先将文件上传到我们的服务器, 然后通过我们的服务器中转再上传到阿里云OSS
service
package com.atguigu.gulimall.mytest.service;
import org.springframework.web.multipart.MultipartFile;
public interface FileService {
//上传文件到阿里云oss
String upload(MultipartFile file);
}
package com.atguigu.gulimall.mytest.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.atguigu.gulimall.mytest.service.FileService;
import com.atguigu.gulimall.mytest.utils.ConstantOssPropertiesUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.joda.time.DateTime;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
@Service
public class FileServiceImpl implements FileService {
@Override
public String upload(MultipartFile file) {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = ConstantOssPropertiesUtils.EDNPOINT;
String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantOssPropertiesUtils.SECRECT;
String bucketName = ConstantOssPropertiesUtils.BUCKET;
try {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 上传文件流。
InputStream inputStream = file.getInputStream();
String fileName = file.getOriginalFilename();
//生成随机唯一值,使用uuid,添加到文件名称里面
String uuid = UUID.randomUUID().toString().replaceAll("-","");
fileName = uuid+fileName;
//按照当前日期,创建文件夹,上传到创建文件夹里面
// 2021/02/02/01.jpg
String timeUrl = new DateTime().toString("yyyy/MM/dd");
fileName = timeUrl+"/"+fileName;
//调用方法实现上传
// 1.jpg /a/b/1.jpg
ossClient.putObject(bucketName, fileName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
//上传之后文件路径
// https://yygh-atguigu.oss-cn-beijing.aliyuncs.com/01.jpg
String url = "https://"+bucketName+"."+endpoint+"/"+fileName;
//返回
return url;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
controller
package com.atguigu.gulimall.mytest.controller;
import com.atguigu.gulimall.mytest.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/oss")
public class OssController {
@Autowired
private FileService fileService;
//上传文件到阿里云oss
@PostMapping("/fileUpload")
public String fileUpload(MultipartFile file) {
//获取上传文件
String url = fileService.upload(file);
return url;
}
}
返回的url也就是图片的访问地址
https://gulimall-oss123.oss-cn-hangzhou.aliyuncs.com/2022/07/23/3f43ae4230064849a0080a93e8964a7d1.jpg
相关文档
这种方式不需要我们的服务器中转文件, 我们的服务器只分发签名, 前端拿着签名直接就将文件上传至阿里云, 效率更高.
service
package com.atguigu.gulimall.mytest.service;
import java.util.Map;
public interface OssService {
Map<String, String> policy();
}
package com.atguigu.gulimall.mytest.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.mytest.service.OssService;
import com.atguigu.gulimall.mytest.utils.ConstantOssPropertiesUtils;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
@Service
public class OssServiceImpl implements OssService {
public Map<String, String> policy() {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = ConstantOssPropertiesUtils.EDNPOINT;
String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantOssPropertiesUtils.SECRECT;
String bucketName = ConstantOssPropertiesUtils.BUCKET;
// 创建OSSClient实例。
OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//https://gulimall-hello.oss-cn-beijing.aliyuncs.com/hahaha.jpg
String host = "https://" + bucketName + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
// String callbackUrl = "http://88.88.88.88:8888";
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dir = format + "/"; // 用户上传文件时指定的前缀。
Map<String, String> respMap = new LinkedHashMap<String, String>();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = client.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = client.calculatePostSignature(postPolicy);
respMap.put("accessid", accessKeyId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
}
return respMap;
}
}
controller
package com.atguigu.gulimall.mytest.controller;
import com.atguigu.gulimall.mytest.service.OssService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.Map;
@RestController
@RequestMapping("/oss")
public class OssController {
@Autowired
private OssService ossService;
@GetMapping("/getPolicy")
public Map<String,String> getPolicy(){
return ossService.policy();
}
}
运行测试
访问http://localhost:9080/oss/getPolicy
返回数据
{
"accessid": "LTAI5tS2xGi7WUz7GbaVnK2z",
"policy": "eyJleHBpcmF0aW9uIjoiMjAyMi0wNy0yM1QwOToyMToyOS45NDFaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIyMDIyLTA3LTIzLyJdXX0=",
"signature": "8O7Suwz2N7uJUIBW3ZqkX96vLkU=",
"dir": "2022-07-23/",
"host": "https://gulimall-oss123.oss-cn-hangzhou.aliyuncs.com",
"expire": "1658568089"
}
用户使用Post方法向OSS发送文件上传请求。
new_multipart_params = {
// key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。
// filename表示待上传的本地文件名称。
'key' : key + '${filename}',
'policy': policyBase64,
'OSSAccessKeyId': accessid,
// 设置服务端返回状态码为200,不设置则默认返回状态码204。
'success_action_status' : '200',
'signature': signature,
};
现在使用postman模拟前端使用签名上传文件
new_multipart_params = {
// key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。
// filename表示待上传的本地文件名称。
'key' : 'images/${filename}',
'policy': "eyJleHBpcmF0aW9uIjoiMjAyMi0wNy0yM1QxMDo1MjozNy4wNThaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJpbWFnZXMvIl1dfQ==",
'OSSAccessKeyId': "LTAI5tS2xGi7WUz7GbaVnK2z",
// 设置服务端返回状态码为200,不设置则默认返回状态码204。
'success_action_status' : '200',
'signature': "hrBlwHN8s8t0ajDuqNjssOUTRTg=",
'file':
};