华为云的obs之自定义springboot-starter

简介: 华为云的obs之自定义springboot-starter

华为云的obs如果自己调用api的话,接口太多,很多不需要,依赖也很多(需要调用好几个jar包)。于是想着自己给封装下,引一个jar就能用多好啊。于是自己利用业余时间自定义了这个starer,可以快速投入开发,省时省力,希望帮助到大家。


一、自定义的starter封装好的几个常用方法:


一.桶的操作


查询所有桶


桶的新增


桶的删除


设置桶内文件对象过期时间


二.对象的操作


1.查询某个桶的所有对象


2.上传某个对象(全局访问权限版2个)(通过流+通过file对象)


3.上传某个对象(设置对象自定义元数据版)


4.获取某个对象的所有信息


5.获取某个对象的元数据


6.获取某个对象的流


7.拷贝对象


8.删除单个对象


9.下载某个对象到本地


三.文件夹的操作


1.创建文件夹


2.判断对象是否是文件夹


3.列举文件夹中的所有对象


4.删除某个文件夹下的所有对象


二、springboot(华为云的obs)的starter核心工具类代码


/**
 * Title: ObsUtils
 * Description: obs操作工具类
 *
 * @author hfl
 * @version V1.0
 * @date 2020-05-27
 */
public class ObsService {
    private final static Logger logger = LoggerFactory.getLogger(ObsService.class);
    private ObsClient obsClient;
    private String bucketName;
    private String bucketLoc;
    private ObsConfiguration config;
    public ObsService() {
    }
    public ObsService(String bucketName, String bucketLoc, ObsConfiguration config) {
        this.bucketName = bucketName;
        this.bucketLoc = bucketLoc;
        this.config = config;
    }
    /**
     * 查询所有桶
     *
     * @return 桶的列表
     */
    @ObsClientAnnotation
    public List<ObsBucket> listBuckets() {
        ListBucketsRequest request = new ListBucketsRequest();
        request.setQueryLocation(true);
        List<ObsBucket> obsBuckets = obsClient.listBuckets(request);
        return obsBuckets;
    }
    /**
     * 桶的新增
     *
     * @param bucketName 桶的名称
     * @return 桶对象信息
     */
    @ObsClientAnnotation
    public ObsBucket createBucket(String bucketName) {
        ObsBucket obsBucket = new ObsBucket(bucketName, bucketLoc);
        obsBucket.setBucketName(bucketName);
        return obsClient.createBucket(obsBucket);
    }
    /**
     * 桶的删除
     *
     * @param bucketName 桶的名称
     * @return 响应对象
     */
    @ObsClientAnnotation
    public HeaderResponse deleteBucket(String bucketName) {
        return obsClient.deleteBucket(bucketName);
    }
    /**
     * 设置桶内指定前缀的文件对象 过期时间
     *
     * @param prefix         什么前缀的文件过期(比如/tmp)
     * @param expirationDays 几天后过期
     */
    @ObsClientAnnotation
    public HeaderResponse setLiftConfig(String prefix, Integer expirationDays) {
        LifecycleConfiguration config = new LifecycleConfiguration();
        LifecycleConfiguration.Rule rule = config.new Rule();
        rule.setEnabled(true);
        //过期规则名称
        rule.setId(String.valueOf(UUID.randomUUID()));
        rule.setPrefix(prefix);
        LifecycleConfiguration.Expiration expiration = config.new Expiration();
        // 指定满足前缀的对象创建x天后过期
        expiration.setDays(expirationDays);
        LifecycleConfiguration.NoncurrentVersionExpiration noncurrentVersionExpiration = config.new NoncurrentVersionExpiration();
        // 指定满足前缀的对象成为历史版本x天后过期
        noncurrentVersionExpiration.setDays(expirationDays);
        rule.setNoncurrentVersionExpiration(noncurrentVersionExpiration);
        config.addRule(rule);
        return obsClient.setBucketLifecycle(bucketName, config);
    }
    /**
     * 查询桶的所有对象
     *
     * @return 桶内对象集合(关键属性getObjectKey)
     */
    @ObsClientAnnotation
    public ObjectListing listObjects() {
        ObjectListing listing = obsClient.listObjects(bucketName);
        return listing;
    }
    /**
     * 上传对象时指定预定义访问策略为公共读(很重要)
     *
     * @param objectKey   对象的key
     * @param inputStream 要上传的文件流
     * @return 响应对象
     */
    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetPreAccessStrategy(String objectKey, InputStream inputStream) {
        PutObjectRequest request = new PutObjectRequest();
        request.setBucketName(bucketName);
        //对象的key 如:  objectname1/text
        request.setObjectKey(objectKey);
        request.setInput(inputStream);
        //设置对象访问权限为公共读
        request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
        return obsClient.putObject(request);
    }
    /**
     * 上传对象时指定预定义访问策略为公共读(很重要)
     *
     * @param objectKey   对象的key
     * @param file 要上传的文件
     * @return 响应对象
     */
    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetPreAccessStrategy(String objectKey, File file) {
        PutObjectRequest request = new PutObjectRequest();
        request.setBucketName(bucketName);
        //对象的key 如:  objectname1/text
        request.setObjectKey(objectKey);
        request.setFile(file);
        //设置对象访问权限为公共读
        request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
        return obsClient.putObject(request);
    }
    /**
     * 上传某个对象并设置对象自定义元数据
     *
     * @param objectKey   要上传的key
     * @param metadata    元数据对象
     * @param inputStream 要上传的文件流
     * @return 上传结果
     * //  ObjectMetadata metadata = new ObjectMetadata();
     * //  metadata.addUserMetadata("property1", "property-value1");
     * //  metadata.getMetadata().put("property2", "property-value2");
     * //  C:\\Users\\hufanglei\\Pictures\\timg.jpg"
     */
    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetMeta(String objectKey, ObjectMetadata metadata, InputStream inputStream) {
        return obsClient.putObject(bucketName, objectKey, inputStream, metadata);
    }
    /**
     * 获取某个对象
     *
     * @param objectKey 对象的key
     * @return 对象的信息
     */
    @ObsClientAnnotation
    public ObsObject getObject(String objectKey) {
        return obsClient.getObject(bucketName, objectKey, null);
    }
    /**
     * 获取某个对象的流
     *
     * @param objectKey 对象的key
     * @return 对象的流
     */
    @ObsClientAnnotation
    public InputStream getObjectInpuStream(String objectKey) {
        ObsObject obsObject = obsClient.getObject(bucketName, objectKey, null);
        return obsObject.getObjectContent();
    }
    /**
     * 查询对象元数据(查询某个对象的具体信息)
     *
     * @param objectKey 要查询的key
     * @return 对象元数据
     */
    @ObsClientAnnotation
    public ObjectMetadata getObjectMetadata(String objectKey) {
        //获取对象元数据
        return obsClient.getObjectMetadata(bucketName, objectKey, null);
    }
    /**
     * 拷贝对象(也可以从一个桶拷贝到另一个桶,这里目前桶和原始文件桶都设置成了配置文件中的桶)
     *
     * @param sourceObjectKey 原始key
     * @param destObjectKey   目标key
     * @return 响应结果
     */
    @ObsClientAnnotation
    public CopyObjectResult copyObject(String sourceObjectKey, String destObjectKey) {
        String sourceBucketName = bucketName;
        String destBucketName = bucketName;
        return obsClient.copyObject(sourceBucketName, sourceObjectKey, destBucketName, destObjectKey);
    }
    /**
     * 删除单个对象
     *
     * @param objectKey 要删除的key
     * @return 响应结果
     */
    @ObsClientAnnotation
    public DeleteObjectResult deletObj(String objectKey) {
        return obsClient.deleteObject(bucketName, objectKey);
    }
    /**
     * 下载某个对象到本地
     *
     * @param objectKey     对象的key
     * @param localFilePath 本地文件路径
     * @throws ObsException
     * @throws IOException
     */
    @ObsClientAnnotation
    public void downloadToLocalFile(String objectKey, String localFilePath) throws ObsException, IOException {
        File localFile = new File(localFilePath);
        if (!localFile.getParentFile().exists()) {
            localFile.getParentFile().mkdirs();
        }
        ObsObject obsObject = obsClient.getObject(bucketName, objectKey, null);
        ReadableByteChannel rchannel = Channels.newChannel(obsObject.getObjectContent());
        ByteBuffer buffer = ByteBuffer.allocate(4096);
        WritableByteChannel wchannel = Channels.newChannel(new FileOutputStream(new File(localFilePath)));
        while (rchannel.read(buffer) != -1) {
            buffer.flip();
            wchannel.write(buffer);
            buffer.clear();
        }
        rchannel.close();
        wchannel.close();
    }
    /**
     * 创建一个文件夹,必须带有/后缀
     *
     * @param keySuffixWithSlash1 文件夹名称(必须带有/后缀)
     * @return 响应对象
     */
    @ObsClientAnnotation
    public PutObjectResult createEmptyFolder(String keySuffixWithSlash1) {
        return obsClient.putObject(bucketName, keySuffixWithSlash1, new ByteArrayInputStream(new byte[0]));
    }
    /**
     * 判断对象是否是文件夹
     * @param keySuffixWithSlash1 文件夹名: 如:   "MyObjectKey1/"
     * @return 布尔值
     */
    @ObsClientAnnotation
    public boolean isEmptyFolder(String keySuffixWithSlash1)  {
        ObsObject object = obsClient.getObject(bucketName, keySuffixWithSlash1, null);
        if (object != null) {
            return object.getMetadata().getContentLength() == 0L;
        }
        return false;
    }
    /**
     * 列举某个文件夹下的所有对象
     *
     * @param folderPrefix 件夹名(必须/结尾)
     * @return 对象集合
     */
    @ObsClientAnnotation
    public ObjectListing listObjectsByFolder(String folderPrefix) {
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置文件夹对象名"dir/"为前缀
        // request.setPrefix("dir/");
        request.setPrefix(folderPrefix);
        //列举文件个数
        request.setMaxKeys(1000);
        ObjectListing result;
        do {
            result = obsClient.listObjects(request);
            for (ObsObject obsObject : result.getObjects()) {
                logger.info("\t" + obsObject.getObjectKey());
                logger.info("\t" + obsObject.getOwner());
            }
            request.setMarker(result.getNextMarker());
        } while (result.isTruncated());
        return result;
    }
    /**
     * 删除某个文件夹下的所有对象
     *
     * @param folderPrefix 文件夹名(必须/结尾)
     * @return 是否删除成功
     */
    @ObsClientAnnotation
    public boolean deleteListObjectsByFolder(String folderPrefix) {
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置文件夹对象名"/xx/xxx/"为前缀
        request.setPrefix(folderPrefix);
        //列举文件个数
        request.setMaxKeys(1000);
        ObjectListing result;
        do {
            result = obsClient.listObjects(request);
            for (ObsObject obsObject : result.getObjects()) {
                logger.info("\t" + obsObject.getObjectKey());
                logger.info("\t" + obsObject.getOwner());
                //执行删除
                obsClient.deleteObject(bucketName, obsObject.getObjectKey());
            }
            request.setMarker(result.getNextMarker());
        } while (result.isTruncated());
        return true;
    }
}


三、如何使用starter


0.前提 请注意


obs的jar包在maven仓库的版本很老了,所以去官网下载比较新的jar包。


需要将esdk-obs-java-3.19.11.1.jar加载进依赖或者上传到私服,我已经上传到自己的私服了,直接引pom即可,直接使用会报错


如果报错,请手动添加放在/obs-upload-spring-boot-starter/doc/lib下esdk-obs-java-3.19.11.1.jar


使用步骤1.引入自定义obs的starter


<dependency>
    <groupId>com.wuzheng</groupId>
    <artifactId>obs-upload-spring-boot-starter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>


使用步骤2.配置文件设置参数


obs:

#端点(xx和地区对应)
  endPoint: http://obs.xxx.myhuaweicloud.com
  ak: yourself ak
  sk: yourslef sk
  bucketName: yourself 桶的名字
  #地区
  bucketLoc: xxx


使用步骤3.在springboot的启动类上加上启动注解


@EnableObsAutoConfiguration


项目中调用示例


@Service
public class UserService {
    @Autowired
    private ObsService obsService;
   //以上传为例:其他方法看上面的接口列表
    public static void obsUp() {
        String objectKey = "XX";
        File file = new File("XXXX");
        obsService.putObjectAndSetPreAccessStrategy(objectKey,  file);        
    }


四、springboot(华为云的obs)starter开源项目地址


https://gitee.com/hufanglei/obs-upload-spring-boot-starter



相关文章
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
155 0
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
163 2
|
2月前
|
Java Spring
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
本文介绍了Spring Boot中静态资源的访问位置、如何进行静态资源访问测试、自定义静态资源路径和静态资源请求映射,以及如何处理自定义静态资源映射对index页面访问的影响。提供了两种解决方案:取消自定义静态资源映射或编写Controller来截获index.html的请求并重定向。
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
|
1月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
61 2
|
1月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
3月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
3月前
|
JSON 安全 Java
|
3月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
181 0
|
4月前
|
消息中间件 Java Kafka
Spring boot 自定义kafkaTemplate的bean实例进行生产消息和发送消息
Spring boot 自定义kafkaTemplate的bean实例进行生产消息和发送消息
187 5