文章目录
- 开启云存储的阿里云
- 使用
-
- 术语
- 创建
- 快速测试上传文件
- java上传
-
- 1 创建子用户
- 2.1 方法1:(推荐方法2)
-
- 步骤
- 代码
-
- pom
- 上传文件
- 2.2 方法2:
-
- pom 引入依赖
- yaml
- 上传上传代码
- 服务端签名后直接传输
-
- 签名的主要内容
- yaml主要内容:
- 编写controller,返回签名信息
- 前端
-
- 上传文件的组件:
-
- 单文件:
- 多文件:
- 从后端获取签名
- ==跨域问题==
本文选择统一存储到云存储
开启云存储的阿里云
-
先贴计费,很便宜 原文:https://www.aliyun.com/price/product?spm=5176.8465980.help.3.4e701450R42spo#/oss/detail/ossbag
-
aliyun官网 - 产品 - oss对象存储
-
开通
- 如果没有实名认证,需要认证,支付宝认证,大约一分钟
使用
术语
- 存储空间
Bucket
存储空间是您用来存储对象的(Object)容器,所有对象都必须属于某个存储空间。 - 对象/文件
Object
对象是 OSS 存储数据的基本单元,被称为OSS文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成对象由存储空间内唯一的对象组成Key来标识。 - 地域
Region
地域表示 OSS 数据中心的物理位置。您可以根据成本、请求来源等综合选择数据存储区域。详情请查看OSS已经开通的Region。 - 访问域名
Endpoint
Endpoint 表示OSS访问域名的外部服务。OSS以HTTP RESTful API以外部服务的形式,当访问不同的区域时,需要不同的域名。通过内部网络和外部网络访问同一区域所需的域名也有所不同。具体内容请参见每个区域Region对应的Endpoint。 - 访问密钥
AccessKey
AccessKey,简称 AK,指访问身份验证中使用的AccessKeyId 和AccessKeySecret。OSS通过使用AccessKeyId 和AccessKeySecret通过对称加密来验证请求的发送者身份。AccessKeyId识别用户,AccessKeySecret加密签名字符串和OSS用于验证签名字符串的密钥AccessKeySecret 必须保密。
创建
- 右侧点创建
- 选项(根据实际需要选择)
快速测试上传文件
- 选择上传文件
- 查看图片 访问如下位置网址:
java上传
java上传文件需要上传到后台,然后上传到后台oss对象存储,自己的服务器也存储了一遍文件,不划算。
服务端签名后上传(本文背后)是指从后台获得签名后直接从前端上传,效率更高。
1 创建子用户
- 通过自己的用户名密码直接验证是不安全的。创建子用户并授权其
- 网址 https://ram.consol.aliyun.com/users
- 如图所示的两个内容相当于用户名密码,要复制下来,一会要用,一会再进来是看不到
AccessKey Secret
内容的! - 授权
- 先返回
- 添加权限
- 添加如下权限
- 成功
2.1 方法1:(推荐方法2)
步骤
代码
pom
- 在Maven项目中加入依赖项 在Maven工程中使用OSS Java SDK,只需在pom.xml中加入相应依赖即可。以3.10.2版本为例,在中加入如下内容:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
- 如果使用的是Java 9及以上的版本,则需要添加jaxb相关依赖。添加jaxb相关依赖示例代码如下:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
上传文件
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "exampledir/exampleobject.txt";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
String filePath= "D:\\localpath\\examplefile.txt";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
// 上传文件。
ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
2.2 方法2:
Alibaba Cloud OSS
: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。 原文:https://github.com/alibaba/aliyun-spring-boot/tree/master/aliyun-spring-boot-samples/aliyun-oss-spring-boot-sample
pom 引入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alicloud-oss -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
- 附上官方文档的依赖,导入失败
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>aliyun-oss-spring-boot-starter</artifactId> </dependency>
yaml
- 配置accessKeyId, secretAccessKey 和region,获取方法原文有
spring:
cloud:
alicloud:
access-key: xx
secret-key: xx
oss:
endpoint: xx
文件上传代码
- 文件上传
@Resource
private OSSClient ossClient;
@Test
public void saveFile() {
// 上传
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "exampledir/exampleobject.txt";
ossClient.putObject(new PutObjectRequest(bucketName, objectName, new File("C:\\Users\\AikeTech\\Pictures\\Saved Pictures\\20220223214433.jpg")));
System.out.println("上传成功。。。");
}
服务端签名后直传
原文:https://help.aliyun.com/document_detail/31926.html
签名主要内容
{
"accessid":"LTAI5tBDFVar1hoq****",
"host":"http://post-test.oss-cn-hangzhou.aliyuncs.com",
"policy":"eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0wNVQyMDoyMzoyM1oiLCJjxb25kaXRpb25zIjpbWyJjcb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVzZXItZGlyXC8i****",
"signature":"VsxOcOudx******z93CLaXPz+4s=",
"expire":1446727949,
"dir":"user-dirs/"
}
Body中的各字段说明如下:
accessid
用户请求的AccessKey ID。
host
用户发送上传请求的域名。
policy
用户表单上传的策略(Policy),Policy为经过Base64编码过的字符串。详情请参见Post Policy。
signature
对Policy签名后的字符串。详情请参见Post Signature。
expire
由服务器端指定的Policy过期时间,格式为Unix时间戳(自UTC时间1970年01月01号开始的秒数)。
dir
限制上传的文件前缀。
yaml主要内容:
spring: cloud: alicloud: access-key: xx secret-key: xx oss: endpoint: xx #
自定义属性bucket bucket: xx server: port: 30000
编写controller,返回签名信息
@RestController
@Slf4j
public class OssController {
@Resource
OSS ossClient;
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
@Value("${spring.cloud.alicloud.access-key}")
String accessId ;
@Value("${spring.cloud.alicloud.secret-key}")
String accessKey ;
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
@Value("${spring.cloud.alicloud.oss.endpoint}")
String endpoint ;
// 填写Bucket名称,例如examplebucket。
@Value("${spring.cloud.alicloud.oss.bucket}")
String bucket ;
// 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
//String callbackUrl = "https://192.168.0.0:8888";
@RequestMapping("/oss/policy")
protected R generatePostPolicy() {
// 填写Host名称,格式为https://bucketname.endpoint。
String host = "https://" + bucket + "." + endpoint;
// 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String dir = format.format(new Date()) + "/";//注意,有/
Map<String, String> respMap = new LinkedHashMap<String, String>();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
// PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap.put("accessid", accessId);
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));
// JSONObject jasonCallback = new JSONObject();
// jasonCallback.put("callbackUrl", callbackUrl);
// jasonCallback.put("callbackBody",
// "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
// jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
// String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
// respMap.put("callback", base64CallbackBody);
} catch (Exception e) {
// Assert.fail(e.getMessage());
log.info(e.getMessage());
} finally {
ossClient.shutdown();
}
return R.ok().put("data", respMap);
}
}
-
其中R是人人开源的类:
/** * 返回数据 * * @author Mark sunlightcs@gmail.com */ public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L; public R() { put("code", 0); put("msg", "success"); } public static R error() { return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员"); } public static R error(String msg) { return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } public R put(String key, Object value) { super.put(key, value); return this; } }
-
附上原文签名上传代码供参考:() https://help.aliyun.com/document_detail/91868.htm?spm=a2c4g.11186623.0.0.1607c9277SiG3G#concept-ahk-rfz-2fb
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。 String accessId = "yourAccessKeyId"; String accessKey = "yourAccessKeySecret"; // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "oss-cn-hangzhou.aliyuncs.com"; // 填写Bucket名称,例如examplebucket。 String bucket = "examplebucket"; // 填写Host名称,格式为https://bucketname.endpoint。 String host = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com"; // 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。 String callbackUrl = "https://192.168.0.0:8888"; // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。 String dir = "exampledir/"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey); try { long expireTime = 30; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。 PolicyConditions policyConds = new PolicyConditions(); policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes("utf-8"); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = ossClient.calculatePostSignature(postPolicy); 标签:
荧光法溶解氧传感器oos61