32-SpringBoot 集成阿里云对象存储OSS

1.开启阿里云OSS服务

1.开启服务

登录阿里云官网
32-SpringBoot 集成阿里云对象存储OSS_第1张图片

开启对象存储服务后(按流量计费),进入对象存储控制台
32-SpringBoot 集成阿里云对象存储OSS_第2张图片
创建Bucket
32-SpringBoot 集成阿里云对象存储OSS_第3张图片

2.配置跨域

如果是微服务项目需要配置跨域
32-SpringBoot 集成阿里云对象存储OSS_第4张图片
创建规则
32-SpringBoot 集成阿里云对象存储OSS_第5张图片
32-SpringBoot 集成阿里云对象存储OSS_第6张图片

3.生成密钥

查看endpoint和url
32-SpringBoot 集成阿里云对象存储OSS_第7张图片

点击头像, 进入Accesskey管理
32-SpringBoot 集成阿里云对象存储OSS_第8张图片
创建AccessKey
32-SpringBoot 集成阿里云对象存储OSS_第9张图片
至此得到信息

bucket:gulimall-oss123
endpoint:oss-cn-hangzhou.aliyuncs.com
url:gulimall-oss123.oss-cn-hangzhou.aliyuncs.com
AccessKey ID:LTAI5tS2xGi7WUz7GbaVnK2z
AccessKey Secret:l5VQHnGdmNLXXPyDTGinhWN8SSMYEU

2.使用方式

阿里云对象存储官方文档

1.引入依赖

        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alicloud-ossartifactId>
        dependency>

2.编写配置

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;
    }
}

3.普通上传

这种上传方式需要先将文件上传到我们的服务器, 然后通过我们的服务器中转再上传到阿里云OSS
32-SpringBoot 集成阿里云对象存储OSS_第10张图片
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;
    }
}

运行测试(我的项目整合了swagger2)
32-SpringBoot 集成阿里云对象存储OSS_第11张图片

返回的url也就是图片的访问地址

https://gulimall-oss123.oss-cn-hangzhou.aliyuncs.com/2022/07/23/3f43ae4230064849a0080a93e8964a7d1.jpg

4.服务端签名后直传

相关文档
32-SpringBoot 集成阿里云对象存储OSS_第12张图片
这种方式不需要我们的服务器中转文件, 我们的服务器只分发签名, 前端拿着签名直接就将文件上传至阿里云, 效率更高.

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': 
 };

32-SpringBoot 集成阿里云对象存储OSS_第13张图片
上传成功
32-SpringBoot 集成阿里云对象存储OSS_第14张图片

你可能感兴趣的:(SpringBoot入门,阿里云,spring,boot,java)