java文件上传到AWS S3 亚马逊(包括删除文件 详细版)

一起探讨学习

欢迎大家进群,一起讨论学习

每天给大家提供技术干货

在这里插入图片描述

博主技术笔记 https://notes.xiyankt.com


博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star https://gitee.com/bright-boy/xiyan-blog


1.maven依赖

    <!-- s3 文件上传 -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.901</version>
        </dependency>

2.yml配置

# S3配置
s3:
  # s3上已经存在该存储桶
  file_bucket: ppm-pics-resource
  # AWS 访问密钥
  access_key: AKIAJdfS3784UINUSEUA
  # AWS SECRET_KEY
  secret_key: PmYSYx1YN/gyZbQBRqdfghj/edvb2qROmgxi+xyq
  # AWS 云平台地址
  url: https://bank-logo-78458784254.s3-accesspoint.us-east-1.amazonaws.com/

3.S3Config

package com.yoostar.config;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
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.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Description:
 *
 * @author: bright
 * @date:Created in 2020/11/19 9:49
 */
@Slf4j
@Configuration
@RefreshScope
public class S3Config{

    /**
     * AWS 访问密钥
     */
    @Value("${s3.access_key}")
    private String accessKey;

    /**
     * AWS SECRET_KEY
     */
    @Value("${s3.secret_key}")
    private String secretKey;

    @Value("${s3.url}")
    private String url;

    /**
     * 初始化生成AmazonS3 客户端配置
     *
     * @return
     */
    @Bean
    public AmazonS3 amazonS3() {
        log.info("start create s3Client");
        AwsClientBuilder.EndpointConfiguration endpointConfig =
                new AwsClientBuilder.EndpointConfiguration(url, Region.getRegion(Regions.US_EAST_1).getName());

        AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
        AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTPS);

        AmazonS3 S3client = AmazonS3Client.builder()
                .withEndpointConfiguration(endpointConfig)
                .withClientConfiguration(clientConfig)
                .withCredentials(awsCredentialsProvider)
                .disableChunkedEncoding()
                .withPathStyleAccessEnabled(true)
                .withForceGlobalBucketAccessEnabled(true)
                .build();
        log.info("create s3Client success");
        return S3client;
    }
}

UploadRecordService

package com.yoostar.service;

import com.yoostar.vo.BaseVO;
import org.springframework.web.multipart.MultipartFile;

/**
 * Description:
 *
 * @author: bright
 * @date:Created in 2020/11/12 18:00
 */
public interface UploadRecordService {
    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    BaseVO upload(MultipartFile file);

    /**
     * 文件删除
     *
     * @param key
     * @return
     */
    BaseVO delete(String key);

}

UploadRecordServiceImpl

package com.yoostar.service.impl;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import com.yoostar.enumeration.ErrorCodeEnum;
import com.yoostar.mapper.UploadRecordMapper;
import com.yoostar.service.UploadRecordService;
import com.yoostar.vo.BaseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * Description:
 *
 * @author: bright
 * @date:Created in 2020/11/16 13:50
 */
@Service
@Slf4j
public class UploadRecordServiceImpl implements UploadRecordService {

    @Resource
    private UploadRecordMapper uploadRecordMapper;

    @Value("${s3.file_bucket}")
    private String fileBucket;

    @Value("${s3.url}")
    private String url;

    @Autowired
    private AmazonS3 amazonS3;

    @Override
    public BaseVO upload(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            log.error("传入的文件名不能为空");
            return new BaseVO(false, ErrorCodeEnum.E0804.getKey(), ErrorCodeEnum.E0804.getValue());
        }
        if (!this.validateFileName(fileName)) {
            log.error("文件名应仅包含汉字、字母、数字、下划线和点号");
            return new BaseVO(false, ErrorCodeEnum.E0805.getKey(), ErrorCodeEnum.E0805.getValue());
        }

        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentLength(file.getSize());

        String key = System.currentTimeMillis() + fileName;
        try {
            PutObjectResult result = amazonS3.putObject(new PutObjectRequest(fileBucket, key, file.getInputStream(), objectMetadata)
                    .withCannedAcl(CannedAccessControlList.BucketOwnerFullControl));   //配置文件访问权限
        } catch (IOException e) {
            e.printStackTrace();
        }
        //文件访问路径
        String address = url + fileBucket + "/" + key;
        log.info(address);
        return null;
    }

    @Override
    public BaseVO delete(String key) {
        amazonS3.deleteObject(new DeleteObjectRequest(fileBucket, key));
        return new BaseVO();
    }

    /**
     * 验证文件名称:仅包含 汉字、字母、数字、下划线和点号
     *
     * @param fileName 文件名称
     * @return 返回true表示符合要求
     */
    private boolean validateFileName(String fileName) {
        String regex = "^[a-zA-Z0-9_\\u4e00-\\u9fa5_\\.]+$";
        return fileName.matches(regex);
    }
}

分段上传可以改为

package com.yoostar.service.impl;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yoostar.constants.Constant;
import com.yoostar.domain.UploadRecordDO;
import com.yoostar.dto.FileDTO;
import com.yoostar.enumeration.ErrorCodeEnum;
import com.yoostar.mapper.UploadRecordMapper;
import com.yoostar.service.UploadRecordService;
import com.yoostar.vo.BaseVO;
import com.yoostar.vo.FileVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Description:
 *
 * @author: bright
 * @date:Created in 2020/11/16 13:50
 */
@Service
@Slf4j
public class UploadRecordServiceImpl implements UploadRecordService {

    @Resource
    private UploadRecordMapper uploadRecordMapper;

    @Value("${s3.url}")
    private String url;

    @Autowired
    private AmazonS3 amazonS3;

    @Override
    public BaseVO upload(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            log.error("传入的文件名不能为空");
            return new BaseVO(false, ErrorCodeEnum.E0804.getKey(), ErrorCodeEnum.E0804.getValue());
        }
        if (!this.validateFileName(fileName)) {
            log.error("文件名应仅包含汉字、字母、数字、下划线和点号");
            return new BaseVO(false, ErrorCodeEnum.E0805.getKey(), ErrorCodeEnum.E0805.getValue());
        }
        //上传 s3 服务器
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentLength(file.getSize());
        String key = System.currentTimeMillis() + fileName;
        try {
            //分段上传
            TransferManager tm = TransferManagerBuilder.standard().withS3Client(amazonS3).build();
            Upload upload = tm.upload(new PutObjectRequest(Constant.fileBucket, key, file.getInputStream(), objectMetadata)
                    //配置文件访问权限
                    .withCannedAcl(CannedAccessControlList.PublicReadWrite));
            upload.waitForCompletion();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //文件访问路径
        String address = url + Constant.fileBucket + "/" + key;

        FileVO fileVO = new FileVO();
        //添加上传记录
        UploadRecordDO uploadRecord = new UploadRecordDO();
        uploadRecord.setInnerName(key);
        uploadRecord.setCreateTime(new Date());
        uploadRecordMapper.insert(uploadRecord);
        fileVO.setDownloadUrl(address);
        return fileVO;
    }

    @Override
    public BaseVO delete(FileDTO fileDTO) {
        amazonS3.deleteObject(new DeleteObjectRequest(Constant.fileBucket, fileDTO.getKey()));
        uploadRecordMapper.delete(new QueryWrapper<UploadRecordDO>().eq("inner_name", fileDTO.getKey()));
        return new BaseVO();
    }

    /**
     * 验证文件名称:仅包含 汉字、字母、数字、下划线和点号
     *
     * @param fileName 文件名称
     * @return 返回true表示符合要求
     */
    private boolean validateFileName(String fileName) {
        String regex = "^[a-zA-Z0-9_\\u4e00-\\u9fa5_\\.]+$";
        return fileName.matches(regex);
    }
}

UploadRecordController

package com.yoostar.controller;

import com.yoostar.service.UploadRecordService;
import com.yoostar.vo.BaseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * Description:
 *
 * @author: bright
 * @date:Created in 2020/11/13 9:05
 */
@Api(tags = "文件集合")
@RequestMapping("/file")
@RestController
public class UploadRecordController {
    @Resource
    private UploadRecordService uploadRecordService;

    @ApiOperation(value = "上传文件接口")
    @PostMapping(value = "/upload")
    public BaseVO upload(MultipartFile file) {
        return uploadRecordService.upload(file);
    }

    @ApiOperation(value = "删除文件接口")
    @DeleteMapping("/delete/{key}")
    public BaseVO delete(@PathVariable("key") String key) {
        return uploadRecordService.delete(key);
    }
}

4.测试

java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第1张图片
java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第2张图片
java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第3张图片

删除文件

java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第4张图片

踩坑记得把这些地址设置不然会出现权限问题和访问不到的问题

java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第5张图片

java文件上传到AWS S3 亚马逊(包括删除文件 详细版)_第6张图片

注意上传大文件nginx需要做如下配置

找到自己主机的nginx.conf配置文件,打开
在http{}中加入
    #客户端文件上传的大小
    client_max_body_size 500m;
    #用于tomcat反向代理,解决nginx 504错误 
    proxy_connect_timeout 300; #单位秒 
    proxy_send_timeout 300; #单位秒 
    proxy_read_timeout 300; #单位秒 
    proxy_buffer_size 16k; 
    proxy_buffers 4 64k; 
    proxy_busy_buffers_size 128k; 
    proxy_temp_file_write_size 128k;
    # ps:以timeout结尾配置项时间要配置大点
然后重启nginx

各位大佬关注下,谢谢。

你可能感兴趣的:(java,文件上传,java,aws)