springboot整合OSS實現文件上傳


OSS

阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。OSS可用於圖片、音視頻、日志等海量文件的存儲。各種終端設備、Web網站程序、移動應用可以直接向OSS寫入或讀取數據。

OSS中得到相關概念

  • Endpoint:訪問域名,通過該域名可以訪問OSS服務的API,進行文件上傳、下載等操作。
  • Bucket:存儲空間,是存儲對象的容器,所有存儲對象都必須隸屬於某個存儲空間。
  • Object:對象,對象是 OSS 存儲數據的基本單元,也被稱為 OSS 的文件。
  • AccessKey:訪問密鑰,指的是訪問身份驗證中用到的 AccessKeyId 和 AccessKeySecret。

OSS服務端簽名后前端直傳的相關說明

1566008566130

流程介紹
  1. Web前端請求應用服務器,獲取上傳所需參數(如OSS的accessKeyId、policy、callback等參數)
  2. 應用服務器返回相關參數
  3. Web前端直接向OSS服務發起上傳文件請求
  4. 等上傳完成后OSS服務會回調應用服務器的回調接口
  5. 應用服務器返回響應給OSS服務
  6. OSS服務將應用服務器回調接口的內容返回給Web前端

整合OSS實現文件上傳

一、添加依賴

        <!-- OSS SDK 相關依賴 -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.5.0</version>
        </dependency>

二、修改配置文件

# OSS相關配置信息
aliyun:
  oss:
    endpoint: xtslife-oss.oss-cn-chengdu.aliyuncs.com # oss對外服務的訪問域名
    accessKeyId: test # 訪問身份驗證中用到用戶標識
    accessKeySecret: test # 用戶用於加密簽名字符串和oss用來驗證簽名字符串的密鑰
    bucketName: xtslife-oss # oss的存儲空間
    policy:
      expire: 300 # 簽名有效期(S)
    maxSize: 10 # 上傳文件大小(M)
    callback: http://localhost:8080/aliyun/oss/callback # 文件上傳成功后的回調地址
    dir:
      prefix: xtslife/images/ # 上傳文件夾路徑前綴

注意:注意:endpoint、accessKeyId、accessKeySecret、bucketName、callback、prefix都要改為你自己帳號OSS相關的,callback需要是公網可以訪問的地址

三、添加OSS的相關java配置

package top.xtslife.practice.config;

import com.aliyun.oss.OSSClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 用於配置OSS的連接客戶端OSSClient。
 * @Author 小濤
 * @Create 2019-08-16  18:04
 */
@Configuration
public class OssConfig {
    @Value("${aliyun.oss.endpoint}")
    private String ALIYUN_OSS_ENDPOINT;
    @Value("${aliyun.oss.accessKeyId}")
    private String ALIYUN_OSS_ACCESSKEYID;
    @Value("${aliyun.oss.accessKeySecret}")
    private String ALIYUN_OSS_ACCESSKEYSECRET;

    @Bean
    public OSSClient ossClient(){
        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
    }
}

四、添加OSS上傳策略封裝對象OssPolicyResult

前端直接上傳文件時所需參數,從后端返回過來。

package top.xtslife.practice.component;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 獲取OSS上傳文件授權返回結果
 * @Author 小濤
 * @Create 2019-08-16  19:05
 */
@Data
public class OssPolicyResult {
    @ApiModelProperty("訪問身份驗證中用到用戶標識")
    private String accessKeyId;
    @ApiModelProperty("用戶表單上傳的策略,經過base64編碼過的字符串")
    private String policy;
    @ApiModelProperty("對policy簽名后的字符串")
    private String signature;
    @ApiModelProperty("上傳文件夾路徑前綴")
    private String dir;
    @ApiModelProperty("oss對外服務的訪問域名")
    private String host;
    @ApiModelProperty("上傳成功后的回調設置")
    private String callback;
}

五、添加OSS上傳成功后的回調參數對象OssCallbackParam

當OSS上傳成功后,會根據該配置參數來回調對應接口

package top.xtslife.practice.component;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * oss上傳成功后的回調參數
 * @Author 小濤
 * @Create 2019-08-16  19:34
 */
@Data
public class OssCallbackParam {
    @ApiModelProperty("請求的回調地址")
    private String callbackUrl;
    @ApiModelProperty("回調是傳入request中的參數")
    private String callbackBody;
    @ApiModelProperty("回調時傳入參數格式,比如表單提交形式")
    private String callbackBodyType;
}

六、OSS上傳成功后的回調結果對象OssCallbackResult

回調接口中返回的數據對象,封裝了上傳文件的信息。

package top.xtslife.practice.component;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @Author 小濤
 * @Create 2019-08-16  19:54
 */
@Data
public class OssCallbackResult {
    @ApiModelProperty("文件名稱")
    private String filename;
    @ApiModelProperty("文件大小")
    private String size;
    @ApiModelProperty("文件的mimeType")
    private String  mimeType;
    @ApiModelProperty("圖片文件的寬")
    private String width;
    @ApiModelProperty("圖片文件的高")
    private String height;
}

七、添加OSS業務接口OssService

package top.xtslife.practice.Service;

import top.xtslife.practice.component.OssCallbackResult;
import top.xtslife.practice.component.OssPolicyResult;

import javax.servlet.http.HttpServletRequest;

/**
 * oss上傳管理Service
 * @Author 小濤
 * @Create 2019-08-16  20:22
 */
public interface OssService {
    /**
     * oss 上傳生成策略
     * @return
     */
    OssPolicyResult policy();

    /**
     * oss上傳成功回調
     * @param request
     * @return
     */
    OssCallbackResult callback(HttpServletRequest request);
}

八、添加OSS業務接口OssService的實現類OssServiceImpl

package top.xtslife.practice.Service.impl;

import cn.hutool.json.JSONUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.xtslife.practice.Service.OssService;
import top.xtslife.practice.component.OssCallbackParam;
import top.xtslife.practice.component.OssCallbackResult;
import top.xtslife.practice.component.OssPolicyResult;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * oss上傳管理Service實現類
 * @Author 小濤
 * @Create 2019-08-16  20:28
 */
@Service
public class OssServiceImpl implements OssService {
    private static final Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
    @Value("${aliyun.oss.policy.expire}")
    private int ALIYUN_OSS_EXPIRE;
    @Value(("${aliyun.oss.maxSize}"))
    private int ALIYUN_OSS_MAX_SIZE;
    @Value("${aliyun.oss.callback}")
    private String ALIYUN_OSS_CALLBACK;
    @Value("${aliyun.oss.bucketName}")
    private String ALIYUN_OSS_BUCKET_NAME;
    @Value("${aliyun.oss.endpoint}")
    private String ALIYUN_OSS_ENDPOINT;
    @Value("${aliyun.oss.dir.prefix}")
    private String ALIYUN_OSS_DIR_PREFIX;

    @Autowired
    private OSSClient ossClient;

    /**
     * 簽名生成
     * @return
     */
    @Override
    public OssPolicyResult policy() {
        OssPolicyResult ossPolicyResult = new OssPolicyResult();
        // 存儲目錄
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dir = ALIYUN_OSS_DIR_PREFIX + sdf.format(new Date());
        // 簽名有效期
        long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
        Date expiration = new Date(expireEndTime);
        // 文件大小
        int maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
        // 回調
        OssCallbackParam ossCallbackParam = new OssCallbackParam();
        ossCallbackParam.setCallbackUrl(ALIYUN_OSS_CALLBACK);
        ossCallbackParam.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
        ossCallbackParam.setCallbackBodyType("application/x-www-form-urlencoded");
        // 提交節點
        String action = "http://"+ ALIYUN_OSS_ENDPOINT;
        try {
            PolicyConditions policyConditions = new PolicyConditions();
            policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE,0,maxSize);
            policyConditions.addConditionItem(MatchMode.StartWith,PolicyConditions.COND_KEY,dir);
            String  postPolicy = ossClient.generatePostPolicy(expiration,policyConditions);
            byte[] binaryData = new byte[0];
            binaryData = postPolicy.getBytes("utf-8");
            String policy = BinaryUtil.toBase64String(binaryData);
            String signature = ossClient.calculatePostSignature(postPolicy);
            String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(ossCallbackParam).toString().getBytes("utf-8"));
            // 返回結果
            ossPolicyResult.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
            ossPolicyResult.setPolicy(policy);
            ossPolicyResult.setSignature(signature);
            ossPolicyResult.setDir(dir);
            ossPolicyResult.setCallback(callbackData);
            ossPolicyResult.setHost(action);
        } catch (Exception e) {
           LOGGER.error("簽名生成失敗",e);
        }
        return ossPolicyResult;
    }

    @Override
    public OssCallbackResult callback(HttpServletRequest request) {
        OssCallbackResult ossCallbackResult = new OssCallbackResult();
        String filename = request.getParameter("filename");
        filename ="http://".concat(ALIYUN_OSS_BUCKET_NAME).concat(".").concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
        ossCallbackResult.setFilename(filename);
        ossCallbackResult.setSize(request.getParameter("size"));
        ossCallbackResult.setMimeType(request.getParameter("mimeType"));
        ossCallbackResult.setWidth(request.getParameter("width"));
        ossCallbackResult.setHeight(request.getParameter("height"));
        return ossCallbackResult;
    }
}

九、添加OssController定義接口

package top.xtslife.practice.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.xtslife.practice.Service.OssService;
import top.xtslife.practice.common.CommonResult;
import top.xtslife.practice.component.OssCallbackResult;
import top.xtslife.practice.component.OssPolicyResult;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author 小濤
 * @Create 2019-08-16  21:46
 */
@RestController
@Api(tags = "OssController",description = "Oss管理")
@RequestMapping("/aliyun/oss")
public class OssController {
    @Autowired
    private OssService ossServiceImpl;
    @ApiOperation("oss上傳簽名生成")
    @GetMapping("/policy")
    public CommonResult<OssPolicyResult> policy(){
        OssPolicyResult ossPolicyResult = ossServiceImpl.policy();
        return CommonResult.success(ossPolicyResult);
    }

    @ApiOperation("oss上傳成功回調")
    @PostMapping("callback")
    public CommonResult<OssCallbackResult> callback(HttpServletRequest request){
        OssCallbackResult ossCallbackResult = ossServiceImpl.callback(request);
        return CommonResult.success(ossCallbackResult);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM