作者Gitee地址 https://gitee.com/thciweicloud
作者项目 面包博客,一个微服务架构的前后端分离博客系统。

面包博客一直想要高效的管理图片资源,为了节约服务器资源,可以选择阿里云OSS存储,并且它和SpringCloud Alibaba又是天然融合

服务流程:用户将图片等资源传到服务器,服务器接收处理后再传给我们的阿里云OSS存储,但这样势必会带来大量的流量带宽消耗;所以有了第二种方式,通过policy策略,也就是提前获取签名的方式,将文件资源和签名共同提交给OSS进行验证继而存储,省去了通过服务器的消耗步骤,完成了资源的节约

下面是代码,以springcloud为例:

如果你使用了springcloud-gateway,网关会对资源传输的大小进行限制,导致报错,所以要进行相应的配置

spring:
  application:
    name: loafblog-picture
  cloud:
    alicloud:
      access-key: xxx
      secret-key: xxx
      oss:
        endpoint: oss-cn-beijing.aliyuncs.com
        bucket: xxx
  servlet:    #配置文件阈值    
   multipart: 
     max-file-size: 10MB
     max-request-size: 100MB
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>
@RestController
@RequestMapping("picture")
public class OssController {
    /**
     * ossClient这里要使用父类
     */
    @Autowired
    OSS ossClient;
    @Autowired
    OssService ossService;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;
    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    @GetMapping("/id")
    public R test1() {
        return R.ok().put("data", 1);
    }

    /**
     * 签名直接上传到oss
     *
     * @return
     */
    @RequestMapping("/oss/policy")
    public R policy() {
        String host = "https://" + bucket + "." + 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 = null;

        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 = new LinkedHashMap<String, String>();
            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));
            //跨域、回调直接删除

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return R.ok().put("data", respMap);
    }

    /**
     * 获取oss文件列表
     */
    @GetMapping("/list")
    public R getOssList() {
        List<OssEntity> data = ossService.getOssList();
        return R.ok().put("data", data);
    }


}

如何获取OSS中存储的文件信息,根据官方文档API

@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint1;
@Value("${spring.cloud.alicloud.oss.bucket}")
private String bucketName;
@Value("${spring.cloud.alicloud.access-key}")
private String accessKeyId;
@Value("${spring.cloud.alicloud.secret-key}")
private String accessKeySecret;

@Override
public List<OssEntity> getOssList() {
    String endpoint = "http://" + endpoint1;
    String prefix = "http://xxx.oss-cn-beijing.aliyuncs.com/";

    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

   // 列举文件。如果不设置KeyPrefix,则列举存储空间下的所有文件。如果设置KeyPrefix,则列举包含指定前缀的文件。
    ObjectListing objectListing = ossClient.listObjects(bucketName);
    List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
    List<OssEntity> collect = sums.stream().map(item -> {
        OssEntity ossEntity = new OssEntity();
        ossEntity.setUrl(prefix + item.getKey());
        ossEntity.setName(item.getKey());
        return ossEntity;
    }).collect(Collectors.toList());


    // 关闭OSSClient。
    ossClient.shutdown();
    return collect;
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐