官方API文档:通过临时URL访问OBS_对象存储服务 OBS_Java_临时授权访问_华为云开发过程中,您有任何问题可以在github上提交issue,或者在华为云对象存储服务论坛中发帖求助。接口参考文档详细介绍了每个接口的参数和使用方法。OBS客户端支持通过访问密钥、请求方法类型、请求参数等信息生成一个在Query参数中携带鉴权信息的URL,可将该URL提供给其他用户进行临时访问。在生成URL时,您需要指定URL的有效期来限制https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0901.html

obs:
  enabled: true #开启 obs
  end-point:  obs.cn-north-4.myhuaweicloud.com #终端节点 默认华北-北京四
  ak: XX #永久accessKey
  sk: XXX #永久secretKey
  socket-timeout:  30000 #socket 超时 默认30s
  connection-timeout: 10000 #connection 超时 默认10s
  bucket-loc: cn-north-4 # 默认 华北-北京四
  expire-seconds: 600 #临时URL有效期,10分钟,单位s秒
  bucket-name: tongyichelianwang-dev
  avatar-folder-name: avatar
  excel-export-folder-name: excel
  certificate-folder-name: certificate
  common-folder-name: common #公共文件夹
  ota-folder-name: ota
package com.nx.saas.cloud.client;

import cn.hutool.core.io.IoUtil;
import com.nx.saas.cloud.model.bean.ObsProperties;
import com.obs.services.ObsClient;
import com.obs.services.ObsConfiguration;
import com.obs.services.model.GetObjectRequest;
import com.obs.services.model.HttpMethodEnum;
import com.obs.services.model.ObsObject;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;


/**
 * obs服务
 *
 * @author hankongbin
 */
@Slf4j
public class ObsServiceClient {

    private ObsClient obsClient;

    private ObsProperties properties;

    public ObsServiceClient(ObsProperties properties) {
        this.properties = properties;
        ObsConfiguration config = new ObsConfiguration();
        config.setSocketTimeout(properties.getSocketTimeout());
        config.setConnectionTimeout(properties.getConnectionTimeout());
        config.setEndPoint(properties.getEndPoint());
        obsClient = new ObsClient(properties.getAk(), properties.getSk(), config);
    }

    /**
     * 获取临时授权url
     *
     * @param objectKey
     */
    public TemporarySignatureResponse getSignUrl(String bucketName, String objectKey, String contentType, boolean publicRead) {
        Map<String, String> headers = new HashMap<>(8);
        if (StringUtils.isBlank(contentType)) {
            contentType = "text/plain";
        }
        headers.put("Content-Type", contentType);
        if (publicRead) {
            headers.put("x-obs-acl", "public-read");
        }
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, properties.getExpireSeconds());
        request.setBucketName(Optional.ofNullable(bucketName).orElse(properties.getBucketName()));
        request.setObjectKey(objectKey);
        request.setHeaders(headers);

        TemporarySignatureResponse response = obsClient.createTemporarySignature(request);

        log.info("Creating object using temporary signature url:{}", response.getSignedUrl());
        return response;
    }

    public byte[] rangeDownload(String bucketName, String objectKey, Long start, Long end) {
        InputStream in = null;
        ByteArrayOutputStream bos = null;
        try {
            GetObjectRequest request = new GetObjectRequest(bucketName, objectKey);
            request.setRangeStart(start);
            request.setRangeEnd(end);
            ObsObject obsObject = obsClient.getObject(request);
            in = obsObject.getObjectContent();
            byte[] buf = new byte[1024];
            bos = new ByteArrayOutputStream();
            int len;
            while ((len = in.read(buf)) != -1) {
                bos.write(buf, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            log.warn("范围下载失败:", e);
        } finally {
            IoUtil.close(bos);
            IoUtil.close(in);
        }
        return null;
    }

}
package com.nx.saas.cloud.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.nx.saas.cloud.client.ObsServiceClient;
import com.nx.saas.cloud.model.request.ObsBatchSignRequest;
import com.nx.saas.cloud.model.request.ObsRangeDownloadRequest;
import com.nx.saas.cloud.model.request.ObsSignRequest;
import com.nx.saas.cloud.model.vo.TempBatchSignatureVo;
import com.nx.saas.cloud.model.vo.TempSignatureVo;
import com.nx.saas.cloud.service.ObsService;
import com.obs.services.model.TemporarySignatureResponse;
import com.wit.tsp.common.api.CommonResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author hankongbin
 * @date 2021/10/23 17:18
 */
@Service
public class ObsServiceImpl implements ObsService {

    @Resource
    private ObsServiceClient obsServiceClient;


    @Override
    public TempSignatureVo getSignUrl(String bucketName, String folder, ObsSignRequest signRequest, boolean publicRead) {
        TempSignatureVo tempSignatureVo = new TempSignatureVo();
        String objectKey = signRequest.getObjectKey();
        String realObjectKey = buildRealObjectKey(folder, objectKey, signRequest.isRenameKey());

        TemporarySignatureResponse response = obsServiceClient.getSignUrl(bucketName, realObjectKey, signRequest.getContentType(), publicRead);
        String accessUrl = new StringBuilder(response.getActualSignedRequestHeaders().get("Host")).append("/").append(realObjectKey).toString();
        tempSignatureVo.setObjectKey(objectKey);
        tempSignatureVo.setUrl(response.getSignedUrl());
        tempSignatureVo.setAccessURL(accessUrl);
        tempSignatureVo.setActualSignedRequestHeaders(response.getActualSignedRequestHeaders());
        return tempSignatureVo;
    }

    @Override
    public TempBatchSignatureVo getSignUrl(String bucketName, String folder, ObsBatchSignRequest signRequest, boolean publicRead) {
        TempBatchSignatureVo tempSignatureVo = new TempBatchSignatureVo();
        List<TempBatchSignatureVo.SignatureItem> items = new ArrayList<>();
        signRequest.getObjectKeys().forEach(item -> {
            String realObjectKey = buildRealObjectKey(folder, item, signRequest.isRenameKey());
            TemporarySignatureResponse response = obsServiceClient.getSignUrl(bucketName, realObjectKey, signRequest.getContentType(), publicRead);
            String accessUrl = new StringBuilder(response.getActualSignedRequestHeaders().get("Host")).append("/").append(realObjectKey).toString();
            TempBatchSignatureVo.SignatureItem signatureItem = new TempBatchSignatureVo.SignatureItem(item, accessUrl, response.getSignedUrl());
            tempSignatureVo.setActualSignedRequestHeaders(response.getActualSignedRequestHeaders());
            items.add(signatureItem);
        });
        tempSignatureVo.setItems(items);
        return tempSignatureVo;
    }

    @Override
    public CommonResult<String> rangeDownload(String bucketName, ObsRangeDownloadRequest request) {
        String url = request.getUrl();
        if (url.startsWith("https://")) {
            url = url.substring(8);
            String objectKey = url.substring(url.indexOf("/") + 1);
            byte[] bytes = obsServiceClient.rangeDownload(bucketName, objectKey, request.getRangeStart(), request.getRangeEnd());
            if (Objects.nonNull(bytes)) {
                return CommonResult.success(Base64.getEncoder().encodeToString(bytes));
            }
        }
        return CommonResult.failed("文件下载失败");
    }

    private String buildRealObjectKey(String folder, String objectKey, boolean rename) {
        StringBuilder sb = new StringBuilder(folder);
        if (!folder.endsWith("/")) {
            sb.append("/");
        }
        sb.append(DateUtil.format(new Date(), "yyyy-MM-dd")).append("/");
        if (rename) {
            sb.append(UUID.randomUUID().toString().replaceAll("-", ""));
            String suffix = getFileExtension(objectKey);
            if (StringUtils.isNotBlank(suffix)) {
                sb.append(suffix);
            }
        } else {
            if (objectKey.startsWith("/")) {
                objectKey = objectKey.substring(1);
            }
            sb.append(objectKey);
        }
        return sb.toString();
    }

    private static String getFileExtension(String objectKey) {
        if (objectKey.lastIndexOf(".") != -1 && objectKey.lastIndexOf(".") != 0) {
            return objectKey.substring(objectKey.lastIndexOf("."));
        } else {
            return "";
        }
    }

}
package com.nx.saas.cloud.model.request;

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

import javax.validation.constraints.NotNull;

/**
 * @author wei.lin
 * @date 2021/11/9
 */
@Data
@ApiModel(description = "_request")
public class ObsSignRequest {
    @ApiModelProperty(value = "文件类型,图片:image/jpeg,默认text/plain")
    private String contentType;
    @NotNull(message = "objectKey不能为空")
    @ApiModelProperty(value = "需要上传的objectKey", required = true)
    private String objectKey;
    @ApiModelProperty(value = "文件是否重命名")
    private boolean renameKey = false;
}
package com.nx.saas.cloud.model.request;

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

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * @author wei.lin
 * @date 2021/11/9
 */
@Data
@ApiModel(description = "_request")
public class ObsBatchSignRequest {

    @ApiModelProperty(value = "文件类型,图片:image/jpeg,默认text/plain")
    private String contentType;
    @NotNull(message = "objectKey集合不能为空")
    @ApiModelProperty(value = "需要上传的objectKey集合", required = true)
    private List<String> objectKeys;
    @ApiModelProperty(value = "文件是否重命名")
    private boolean renameKey = false;
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐