上传文件至华为云OBS

1 创建华为云Bucket

1.1 创建Bucket

1.2 获取Bucket的Endpoint

1.3 获取访问凭证

**注:**每个访问密钥仅能下载一次,为了账号安全性,建议您定期更换并妥善保存访问密钥。不再使用的访问密钥,建议停用和删除。

2 创建Sprint Boot工程

创建一个如下图所示的工程,其中common模块用于存在通过的工具、文件和类等;pojo模块用于存放实体、vo和dto;server模块则用于实现业务功能。

2.1 配置OBS参数

在server模块下,创建如下图所示的两个配置文件

在application-dev.yml配置文件中配置OBS参数,示例如下:

复制代码
test:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    ......此处省略其它配置内容......

  hwobs:
    endpoint: obs.cn-north-4.myhuaweicloud.com
    accessKeyId: HP........................G98
    accessKeySecret: aK...........................fiC
    bucketName: ptu........................ut

**注:**以上hwobs中的各参数值要替换成自己的。

在application.yml配置文件中动态引用application-dev.yml配置文件中的内容,示例如下:

复制代码
server:
  port: 8080

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  profiles:
    active: dev
  main:
    allow-circular-references: true
  datasource:
    druid:
      driver-class-name: ${test.datasource.driver-class-name}
      ......此处省略其它配置内容......

  hwobs:
    endpoint: ${test.hwobs.endpoint}
    accessKeyId: ${test.hwobs.accessKeyId}
    accessKeySecret: ${test.hwobs.accessKeySecret}
    bucketName: ${test.hwobs.bucketName}

2.2 添加HWOBS依赖

2.2.1 配置全局pom.xml文件

在全局pom.xml文件中添加Huawei OBS的SDK依赖

示例如下:

复制代码
    <properties>
        ......其它内容......
        <hw.sdk.obs>3.23.9</hw.sdk.obs>
        ......其它内容......
    </properties>
    <dependencyManagement>
        <dependencies>
            ......其它内容......
            <dependency>
                <groupId>com.huaweicloud</groupId>
                <artifactId>esdk-obs-java-bundle</artifactId>
                <version>${hw.sdk.obs}</version>
            </dependency>
            ......其它内容......
        </dependencies>
    </dependencyManagement>

2.2.2 配置通用模块的pom.xml文件

配置通用模块common下的pom.xml

示例内容如下:

复制代码
    <dependencies>
        ......其它内容......
        <dependency>
            <groupId>com.huaweicloud</groupId>
            <artifactId>esdk-obs-java-bundle</artifactId>
        </dependency>
        ......其它内容
    </dependencies>

2.3 创建HwObs的属性类

在common模块下的properties包中添加HwObsProperties属性类

文件内容示例如下:

复制代码
package ptu.test.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "test.hwobs")
@Data
public class HwObsProperties {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}

2.4 创建HwObsUtil工具类

在common模块下的utils包中添加HwObsUtil工具类

示例内容如下:

复制代码
package ptu.test.utils;

import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;

@Data
@AllArgsConstructor
@Slf4j
public class HwObsUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

// 创建ObsClient实例
        // 使用配置文件中的accessKeyId, accessKeySecret初始化客户端
        ObsClient obsClient = new ObsClient(accessKeyId, accessKeySecret, endpoint);

        try {// 创建PutObject请求
            obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (ObsException e) {
            System.out.println("putObject failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } finally {
            if (obsClient != null) {
                try {
                    obsClient.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            //文件访问路径规则 https://BucketName.Endpoint/ObjectName
            StringBuilder stringBuilder = new StringBuilder("https://");
            stringBuilder
                    .append(bucketName)
                    .append(".")
                    .append(endpoint)
                    .append("/")
                    .append(objectName);

            log.info("文件上传到:{}", stringBuilder.toString());
            return stringBuilder.toString();
        }
    }
}

2.5 创建统一返回结果类

在common模块下的result包中创建Result类,用于统一返回结果

文件内容示例如下:

复制代码
package ptu.test.result;

import lombok.Data;

import java.io.Serializable;

/**
 * 后端统一返回结果
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败
    private String msg; //错误信息
    private T data; //数据

    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }

    public static <T> Result<T> success(T object) {
        Result<T> result = new Result<T>();
        result.data = object;
        result.code = 1;
        return result;
    }

    public static <T> Result<T> error(String msg) {
        Result result = new Result();
        result.msg = msg;
        result.code = 0;
        return result;
    }

}

2.6 创建ObsConfiguration类

在需要文件上传的server模块,创建一个config包,并在其中创建一个ObsConfiguration类

示例内容如下:

复制代码
package ptu.test.config;

import ptu.test.properties.HwObsProperties;
import ptu.test.utils.HwObsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 自定义配置类,用于创建HwObsUtil 对象
 */
@Configuration
@Slf4j
public class ObsConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public HwObsUtil hwObsUtil(HwObsProperties hwObsProperties) {
        //log.info("创建华为云文件上传工具类对象:{}", hwObsProperties);
        return new HwObsUtil(hwObsProperties.getEndpoint(),
                hwObsProperties.getAccessKeyId(),
                hwObsProperties.getAccessKeySecret(),
                hwObsProperties.getBucketName());
    }
}

2.7 实现文件上传

在server模块下的controller包下创建CommonController类

实现上传文件的示例代码如下:

复制代码
package ptu.test.controller;

import ptu.test.constant.MessageConstant;
import ptu.test.result.Result;
//import com.sky.utils.AliOssUtil;
import ptu.test.utils.HwObsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * 通用控制类
 */
@RestController
@RequestMapping("/admin/common")
@Slf4j
@Api(tags = "通用接口")
public class CommonController {

    @Autowired
    private HwObsUtil hwObsUtil;

    /**
     * 文件上传至华为云
     * @param file
     * @return
     */
    @PostMapping("upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file) {
        log.info("上传文件:{}", file);

        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();

        // 获取原始文件的扩展名
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 生成带UUID的新文件名
        String objectName = UUID.randomUUID().toString() + extension;

        //上传文件,并获取新文件的访问路径
        try {
            String filePath = hwObsUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}", e.getMessage());
        }
        return Result.error("文件上传失败");
    }
}