Springboot集成Amazon-S3对象存储桶与工具类实现

一、Amazon S3介绍:

官方介绍:amazon (S3) 是一个公开的服务,Web 应用程序开发人员可以使用它存储数字资产,包括图片、视频、音乐和文档。 S3 提供一个 RESTful API 以编程方式实现与该服务的交互。

通俗理解:以桶作为容器。以桶内全路径作为key,以文件作为value的文件存储方式

二、springboot集成Amazon s3

在项目的pom文件中增加如下依赖

        <!--aws s3-->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.336</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-core</artifactId>
            <version>1.11.336</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-kms</artifactId>
            <version>1.11.336</version>
        </dependency>

三、Amazon S3工具类

实现功能:

方法             方法名
创建s3的客户端连接public AmazonS3 createS3Client(String accessKeyId,String secretAccessKey,String endPoint)
上传文件public boolean uploadFile(File file, String fileKey)
上传文件流  public boolean uploadFileByStream(InputStream inputStream, String fileKey)
从s3下载文件public InputStream downloadFile(String fileKey)
 
同一个桶内移动文件public boolean mvFile(String oldFileKey,String newFileKey)
 
删除单个文件public boolean deleteFile(String fileKey)
 
删除多个文件public boolean deleteFiles(String[] fileList)
 
查看文件是否存在public boolean exist(String fileKey)
 
根据prefix获取文件列表public List<S3ObjectSummary> searchPathFileByPrefix(String prefix)
 
生成文件的预签名urlpublic String generalUrl(String fileKey)
 
根据预签名url下载文件public File downloadFromUrl(String url,String filePath)
 
package com.testcase.s3;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**
 * Created with IntelliJ IDEA.
 * Description:Amazon s3工具类
 * User: rice
 */
@Log4j2
public class S3ToolUtils {

    //S3访问密钥
    private String accessKeyId;
    //S3加密访问密钥
    private String secretAccessKey;
    //服务端点
    private String endPoint;
    //桶名
    private String bucketName;

    public S3ToolUtils(String accessKeyId, String secretAccessKey, String endPoint) {
        this.accessKeyId = accessKeyId;
        this.secretAccessKey = secretAccessKey;
        this.endPoint = endPoint;
        this.bucketName = bucketName;
    }

    /**
     * 创建一个对象存储桶客户端连接
     * @param accessKeyId:AWS访问密钥
     * @param secretAccessKey:AWS加密访问密钥
     * @param endPoint:服务端点
     * @return AmazonS3
     */
    public AmazonS3 createS3Client(String accessKeyId,String secretAccessKey,String endPoint){
        //创建s3 client
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        //添加客户端最大连接数
        clientConfiguration.setMaxConnections(1000);
        AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
        AmazonS3 client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, Regions.CN_NORTH_1.getName()))
                .withClientConfiguration(clientConfiguration)
                .withPathStyleAccessEnabled(true).build();
        return client;
    }

    /**
     * 上传文件到对象存储桶
     * @param file
     * @param fileKey
     * @return Boolean
     */
    public boolean uploadFile(File file, String fileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //上传文件
            s3Client.putObject(bucketName,fileKey,file);
        }catch (Exception e){
            log.error(e);
            return false;
        }
        return true;
    }

    /**
     * 上传文件到对象存储桶-文件流方式
     * @param inputStream
     * @param fileKey
     * @return boolean
     */
    public boolean uploadFileByStream(InputStream inputStream, String fileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //上传文件
            s3Client.putObject(bucketName,fileKey,inputStream,new ObjectMetadata());
        }catch (Exception e){
            log.error(e);
            return false;
        }
        return true;
    }

    /**
     * 下载文件
     * @param fileKey
     * @return
     */
    public InputStream downloadFile(String fileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //上传文件
            S3Object object = s3Client.getObject(bucketName, fileKey);
            return object.getObjectContent();
        }catch (Exception e){
            log.error(e);
            return null;
        }
    }


    /**
     * 移动文件(删除原文件)
     * @param oldFileKey 原全路径
     * @param newFileKey 新全路径
     * @return boolean
     */
    public boolean mvFile(String oldFileKey,String newFileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //复制文件
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, oldFileKey, bucketName, newFileKey);
            s3Client.copyObject(copyObjectRequest);
            //删除原文件
            s3Client.deleteObject(new DeleteObjectRequest(bucketName,oldFileKey));
        }catch (Exception e){
            log.error(e);
            return false;
        }
        return true;
    }

    /**
     * 删除文件
     * @param fileKey 删除文件全路径
     * @return boolean
     */
    public boolean deleteFile(String fileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //删除文件
            s3Client.deleteObject(bucketName,fileKey);
        }catch (Exception e){
            log.error(e);
            return false;
        }
        return true;
    }

    /**
     * 删除文件列表
     * @param fileList
     * @return
     */
    public boolean deleteFiles(String[] fileList){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //删除多个文件
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(fileList);
            s3Client.deleteObjects(deleteObjectsRequest);
        }catch (Exception e){
            log.error(e);
            return false;
        }
        return true;
    }

    /**
     * 查找桶内文件是否存在
     * @param fileKey
     * @return
     */
    public boolean exist(String fileKey){
        //获取客户端连接
        AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
        ListObjectsV2Result listObjectsV2Result = s3Client.listObjectsV2(bucketName, fileKey);
        return listObjectsV2Result.getKeyCount()>0;
    }

    /**
     * 根据prefix获取文件列表
     * 注意:若不进行do-while,只进行一次s3Client.listObjectsV2(req),则最多展示1000条
     * @param prefix
     * @return
     */
    public List<S3ObjectSummary> searchPathFileByPrefix(String prefix){
        ArrayList<S3ObjectSummary> returnList = new ArrayList<>();
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //按prefix获取文件列表
            ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucketName);
            ListObjectsV2Result result;
            if(prefix!=null &&!prefix.isEmpty()){
                req = req.withPrefix(prefix);
            }
            do{
                result = s3Client.listObjectsV2(req);
                returnList.addAll(result.getObjectSummaries());
                String token = result.getNextContinuationToken();
                req.setContinuationToken(token);
            }while(result.isTruncated());
            return returnList;
        }catch (Exception e){
            log.error(e);
            return null;
        }
    }


    /**
     * 生成文件的预签名URL
     * 注意:
     * 1.有url,无需通过密钥连接对象存储桶,只用http请求就能下载文件
     * 2.url最多7天有效,官方限制。所以必须考虑url刷新
     * @param fileKey
     * @return
     */
    public String generalUrl(String fileKey){
        try{
            //获取客户端连接
            AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint);
            //设置预签名失效时间-最多七天
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_MONTH,7);
            Date date = calendar.getTime();
            //生成预签名链接
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileKey)
                    .withMethod(HttpMethod.GET)
                    .withExpiration(date);
            URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
            return url.toString();
        }catch (Exception e){
            log.error(e);
            return null;
        }
    }

    /**
     * 根据url下载文件到本地
     * @param url
     * @param filePath
     * @return
     * @throws IOException
     */
    public File downloadFromUrl(String url,String filePath) throws IOException {
        //获取文件名
        String tmpUrl = StringUtils.substring(url,url.indexOf("//")+2);
        int startPos = StringUtils.indexOf(tmpUrl,"/",tmpUrl.indexOf("/")+1)+1;
        int endPos = StringUtils.indexOf(tmpUrl,"?");
        tmpUrl = StringUtils.substring(tmpUrl,startPos,endPos);
        String fileName = Paths.get(StringUtils.replace(tmpUrl,"%2F","/")).getFileName().toString();

        //http请求
        HttpClient client = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();

        //输出文件
        File file = new File(filePath + "/" + fileName);
        if(!file.getParentFile().exists()&&!file.getParentFile().isDirectory()){
            file.getParentFile().mkdir();
        }
        try(InputStream is = entity.getContent();
        FileOutputStream fileout = new FileOutputStream(file)){
            byte[] buffer = new byte[10 * 1024];
            int ch = 0;
            while((ch = is.read(buffer))!=-1){
                fileout.write(buffer,0,ch);
            }
            fileout.flush();
            return file;
        }catch (Exception e){
            return null;
        }
    }
    
}

四、总结:

Amazon s3可以替代nas进行文件存储,在分布式架构中非常适用。

除了以上基础的使用外,还有分片下载、断点续传、异常处理等场景以及s3Browser工具的使用,后续进行分享。

PS:若有错漏,欢迎大家指正与讨论,谢谢~

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot项目中集成AWS SDK,可以实现AWS S3的连接并实现文件的上传和下载功能。 首先,需要在pom.xml文件中添加AWS SDK的依赖项,并确保version保持一致。在dependencyManagement中添加以下代码: ``` <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.0.0-preview-12</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` 然后,在dependencies中添加以下代码: ``` <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.0.0-preview-12</version> </dependency> ``` 接下来,在application.properties文件中进行配置,包括AWS的访问密钥、S3存储名称、存储所在地区以及上传文件的路径: ``` aws.access_key_id=your access key aws.secret_access_key=your secret access key aws.s3.bucket=your bucket name aws.s3.region=cn-northwest-1 aws.s3.filename=/666666/test123/photo.zip ``` 在文件上传和下载的方法中,需要注意传递给方法的key参数是指存储在AWS S3上的文件名。如果key参数是路径字符串格式,S3服务器会自动创建对应路径的文件夹。例如,如果在application.properties中设置了aws.s3.filename=/666666/test123/photo.zip,那么key参数为/666666/test123/photo.zip,S3存储下就会有一个名为/666666/test123/photo.zip的文件,即上传的文件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring Boot项目集成AWS SDK连接到AWS S3,实现上传下载功能](https://blog.csdn.net/sinat_27428951/article/details/89675587)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值