使用联通云OSS小程序直传


前言

因为给某市做一个核酸预约登记扫码的防疫系统需要和联通合作,采用了联通云的对象存储技术,希望能给使用联通OSS的小伙伴们踩个坑。


一、对象存储OSS?

对象存储产品(Object Storage Service,简称 OSS),是提供的海量、安全、低成本、高可靠的云存储服务。

二、使用步骤

1.POM引入

引入亚马逊aws依赖:

	<dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.11.24</version>
    </dependency>

2.对象上传

代码如下(示例):

		// 此处的AK和SK填写自己的
 		BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials("accessKey", "secretKey");

        // 创建OSSClient实例。
        AmazonS3 amazonS3 = new AmazonS3Client(basicAWSCredentials);
        // 设置endpoint
        amazonS3.setEndpoint("https://obs-jsnj.woyun.cn");

        S3ClientOptions s3ClientOptions = S3ClientOptions.builder().setPathStyleAccess(true).setPayloadSigningEnabled(true).build();
        amazonS3.setS3ClientOptions(s3ClientOptions);

        // 桶名称
        String bucketName = "demo";

        try {

            /**
             * =======================  上传 =====================================================
             */
            String objectKey = "甘雨神里.jpg";
            File file = new File("/Users/ddogring/Pictures/甘雨神里.jpeg");
            String fileName = file.getName();
            objectKey = String.format(objectKey, fileName);
            // 判断桶是否存在
            if (!amazonS3.doesBucketExist(bucketName)) {
                // 创建桶实例(容器, 无需重复创建)
                amazonS3.createBucket(bucketName);
            }
            // 创建对象请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, file);
            
            // 也可以文件流方式上传
            // InputStream is = new FileInputStream(file);
            // ObjectMetadata metadata =  new ObjectMetadata();
            // metadata.setContentType(fileName);
            // PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, is, metadata);
            
            // 设置读写权限
            putObjectRequest.withCannedAcl(CannedAccessControlList.Private);
            // 提交对象
            PutObjectResult result = amazonS3.putObject(putObjectRequest);

            if (Objects.nonNull(result)){
                System.out.println("result:=============================================================");
                System.out.println("result.getContentMd5():"+result.getContentMd5());
                System.out.println("result.getETag():"+result.getETag());
                System.out.println("result.getMetadata():"+result.getMetadata());
                System.out.println("result.getVersionId():"+result.getVersionId());
                System.out.println("result.getExpirationTimeRuleId():"+result.getExpirationTimeRuleId());
                System.out.println("result.getExpirationTime():"+result.getExpirationTime());
            }
        } catch (Exception e){
            e.printStackTrace();
        }

3.关于AK和SK的获取

登陆联通云,进入控制台,当时找了好久才发现,链接这么小!!!

在这里插入图片描述

4.关于微信小程序直传

因为我们做的是微信小程序,考虑到带宽和安全问题,不考虑服务端上传而采用微信小程序直传。

联通云OSS官方文档

https://www.cucloud.cn/document.html?id=572&arcid=1

此时小程序端需要向应用服务端获取签名,获取签名方法详见

https://www.jianshu.com/p/fbfb43b96829

以下是Java生成签名代码部分

	/**
     * 获取oss认证签名
     * @author DdogRing
     * @date 2022/4/13 0013 16:21
     * @param
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    public Map<String, Object> getSignature() throws Exception {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        Calendar calendar = Calendar.getInstance();
        // policy有效期10分钟
        calendar.add(Calendar.MINUTE, - (8 * 60) + 10);
        Date time = calendar.getTime();
        String format = sdf.format(time);

        // 生成policy
        String policy = "{\"expiration\": \""+ format +"\",\"conditions\": [[\"eq\",\"$bucket\", \""

                + bucketName + "\" ],[\"starts-with\", \"$key\", \"" + objectName

                + "\"],[\"content-length-range\", 0, 104857600],[\"eq\",\"$Content-Type\", \"text/plain\"],{\"acl\":\""

                + CannedAccessControlList.Private +"\"}]}";

        // policy加密
        String encodePolicy = new String(Base64.getEncoder().encode(policy.getBytes()));
        // 计算签名
        String signature = computeSignature(accessKeySecret, encodePolicy);

        Map<String, Object> res = new HashMap<>();
        res.put("accessKeyId", "accessKey");
        res.put("encodePolicy", encodePolicy);
        res.put("signature", signature);
        res.put("filename", objectName);
        return res;

    }
    
	/**
     * 计算签名
     * @author DdogRing
     * @date 2022/4/13 0013 16:22
     * @param key accessKeySecret
     * @param data base64后的policy
     * @return java.lang.String
     */
    public String computeSignature(String key, String data) {

        try {

            byte[] signData = sign(key.getBytes(DEFAULT_ENCODING), data.getBytes(DEFAULT_ENCODING), macInstance, LOCK,

                    ALGORITHM);

            return BinaryUtils.toBase64(signData);

        } catch (UnsupportedEncodingException ex) {

            throw new RuntimeException("Unsupported algorithm: " + DEFAULT_ENCODING, ex);

        }

    }

    protected byte[] sign(byte[] key, byte[] data, Mac macInstance, Object lock, String algorithm) {

        try {

            if (macInstance == null) {

                synchronized (lock) {

                    if (macInstance == null) {

                        macInstance = Mac.getInstance(algorithm);

                    }

                }

            }

            Mac mac;

            try {

                mac = (Mac) macInstance.clone();

            } catch (CloneNotSupportedException e) {

                mac = Mac.getInstance(algorithm);

            }

            mac.init(new SecretKeySpec(key, algorithm));

            return mac.doFinal(data);

        } catch (NoSuchAlgorithmException ex) {

            throw new RuntimeException("Unsupported algorithm: " + algorithm, ex);

        } catch (InvalidKeyException ex) {

            throw new RuntimeException("Invalid key: " + key, ex);

        }

    }

总结

联通云OSS对象存储的官方文档还有待完善(很多地方其实是有出入的),最后都是翻阅亚马逊S3的文档、阿里云OSS文档和联系联通云的技术专家解决的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值