SpringBoot整合Amazon S3实现文件上传、下载、删除

发布时间 2023-04-24 20:50:32作者: yvioo

 

依赖

<dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.490</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>1.25</version>
        </dependency>

 

 

也引入了,如果已经引入了 ,就不需要了,也可以用自己的方法

  <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

 

 

yml配置信息

file:
  ceph:
    endpoint: http://192.168.1.159:7480
    access:
      key: NE54EF
    secret:
      key: XdYuYM
    bucket:
      name: fileph

 

 

上传工具类

CephComponent.java

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
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.AmazonS3Client;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import com.example.ceph.exception.MyException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;

@Component
@Slf4j
public class CephComponent {


    @Value("${file.ceph.endpoint}")
    private String FILE_CEPH_POINT;

    @Value("${file.ceph.access.key}")
    private String FILE_CEPH_ACCESS_KEY;

    @Value("${file.ceph.secret.key}")
    private String FILE_CEPH_SECRET_KEY;

    @Value("${file.ceph.bucket.name}")
    private String FILE_CEPH_BUCKET_NAME;

    /**
     * aws s3 client
     */
    AmazonS3 s3 = null;

    @PostConstruct
    public void init() {

        ClientConfiguration config = new ClientConfiguration();
        config.setMaxConnections(200);
        AwsClientBuilder.EndpointConfiguration endpointConfig =
                new AwsClientBuilder.EndpointConfiguration(FILE_CEPH_POINT, Regions.CN_NORTH_1.getName());

        AWSCredentials awsCredentials = new BasicAWSCredentials(FILE_CEPH_ACCESS_KEY, FILE_CEPH_SECRET_KEY);
        AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);

        s3 = AmazonS3Client.builder()
                .withEndpointConfiguration(endpointConfig)
                .withClientConfiguration(config)
                .withCredentials(awsCredentialsProvider)
                .disableChunkedEncoding()
                .withPathStyleAccessEnabled(true)
                .build();

        log.debug("完成初始化AWS访问组件");
    }

    /**
     * @param savePath    文件保存相对路径 格式:/文件名/
     * @param fileName    文件名
     * @param contentType
     * @param fileSize
     * @param in
     * @return 桶名称
     * @throws Exception
     */
    public String putIn(String savePath, String fileName, String contentType, long fileSize, InputStream in) throws MyException {
        log.info("开始上传文件【relativeSavePath={}】 【fileName={}】", savePath, fileName);

        try {
            //检查Bucket是否存在
            if (!s3.doesBucketExistV2(FILE_CEPH_BUCKET_NAME)) {
                s3.createBucket(FILE_CEPH_BUCKET_NAME);
                s3.setBucketAcl(FILE_CEPH_BUCKET_NAME, CannedAccessControlList.PublicReadWrite);
            }
        } catch (Exception e) {
            //这里初始化会抛出异常,自行修改
            throw new MyException("初始化AmazonS3 BUCKET失败", e);
        }
        String filePath = StringUtils.isBlank(savePath) ? FILE_CEPH_BUCKET_NAME : FILE_CEPH_BUCKET_NAME + savePath;
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(contentType);
        objectMetadata.setContentLength(fileSize);
        //上传文件到S3
        s3.putObject(filePath, fileName, in, objectMetadata);

        log.info("上传文件 {} 到S3成功,绝对路径:{}", fileName, filePath);

        return FILE_CEPH_BUCKET_NAME;
    }


    /**
     * 删除文件
     *
     * @param savePath 文件保存路径 格式:/文件名/
     * @param key
     */
    public void deleteFile(String savePath, String key) throws Exception {
        s3.deleteObject(FILE_CEPH_BUCKET_NAME + savePath, key);
    }


    /**
     * 下载文件
     *
     * @param savePath 文件保存路径 格式:/文件名/
     * @param key      文件名称
     * @param response
     * @throws Exception
     */
    public void downloadFile(String savePath, String key, HttpServletResponse response) throws Exception {
        S3Object object;
        try {
            object = s3.getObject(new GetObjectRequest(FILE_CEPH_BUCKET_NAME + savePath, key));
        } catch (AmazonS3Exception e) {
            log.info("【fileName={}】 文件不存在", key);
            return;
        }
        S3ObjectInputStream inputStream = object.getObjectContent();
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("1.xlsx", "UTF-8"));
        IOUtils.copy(inputStream, response.getOutputStream());
        inputStream.close();
    }
}

 

 

 

上传demo

    @Resource
    private CephComponent cephComponent;


    /**
     * 文件保存到ceph服务器
     *
     * @return
     */
    @PostMapping(value = "/uploadToAmazonS3")
    public String uploadToAmazonS3(MultipartFile file) throws Exception {

        Tika tika = new Tika();
        String fileContentType = tika.detect(file.getInputStream());

        //图片在服务器相对保存路径 /appCode/2022/01/12
        String relativeSavePath = "/aa964cfd-7e74-48a0-8300-3b8436bd4811/534fb672-bf62-429a-a0ea-0855499006dc/";


        String fileName = UUID.randomUUID().toString();
        System.out.println(fileName);
        //上传原始图片
        //获取文件在S3服务器上的完整路径
        String bucketName = cephComponent.putIn(relativeSavePath, fileName, fileContentType, file.getSize(), file.getInputStream());

        return fileName;

    }