依赖
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.4version>
dependency>
<dependency>
<groupId>com.amazonawsgroupId>
<artifactId>aws-java-sdk-s3artifactId>
<version>1.12.198version>
dependency>
接口层
private final AwsS3Service awsS3Service;
private static final String bucket = "s3Demo";
public GpLandPageController(AwsS3Service awsS3Service) {
this.awsS3Service = awsS3Service;
}
@PostMapping("/upload")
public String uploadImage(@RequestParam("file") @NotNull MultipartFile file) {
return awsS3Service.uploadFileToS3(bucket, file);
}
@PostMapping("/preUpload")
public PreUploadRes preUpload(@RequestParam("fileName") @NotEmpty String fileName) {
return awsS3Service.preUploadFile(bucket, fileName);
}
service接口层
PreUploadRes preUploadFile(String bucket, String fileName);
public AwsS3UploadFileResDto uploadFileToS3(String bucket, MultipartFile file);
service实现层
private static final String PREFIX = "demo";
@Override
public PreUploadRes preUploadFile(String bucket, String fileName) {
PreUploadRes res = new PreUploadRes();
try {
AmazonS3 amazonS3 = s3client();
String fastFileName = getFileKey(prefix);
DateTime expiration = DateUtil.offsetHour(new Date(), 1);
URL url = amazonS3.generatePresignedUrl(new GeneratePresignedUrlRequest(bucket, fastFileName).withExpiration(expiration).withMethod(HttpMethod.PUT));
res.setKey(fastFileName).setUrl(url.toString());
log.info("Generate preUrl Request is success :{}", JSONUtil.toJsonStr(res));
} catch (Exception e) {
log.error("Generate preUrl Request is failure :{}", e.getMessage(), e);
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
return res;
}
@Override
public AwsS3UploadFileResDto uploadFileToS3(String bucket, MultipartFile file) {
String fastFileName = getFileKey(file.getOriginalFilename());
try {
PutObjectRequest request = new PutObjectRequest(bucket, fastFileName, file.getInputStream(), null);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(file.getContentType());
request.setMetadata(metadata);
PutObjectResult putObjectResult = s3client().putObject(request);
GpLandPageConfigDto config = getConfig();
String url = config.getCdnPrefix() + "/" + fastFileName;
log.info("upload to s3 bucket:{} file:{} url:{} is success ! ===> putRes:{}", bucket, fastFileName, url, JSONUtil.toJsonStr(putObjectResult));
AwsS3UploadFileResDto awsS3UploadFileResDto = new AwsS3UploadFileResDto().setS3PutRes(putObjectResult);
awsS3UploadFileResDto.setFileName(fastFileName);
awsS3UploadFileResDto.setBucketName(bucket);
awsS3UploadFileResDto.setFileUrl(url);
return awsS3UploadFileResDto;
} catch (Exception e) {
log.error("upload original file:{}, fastFileName:{} to S3 is Error:{}", file.getName(), fastFileName, e.getMessage());
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
}
public AmazonS3 s3client() {
try {
AtomicReference<AmazonS3> res = new AtomicReference<>();
Regions regions = Regions.fromName(regions);
res.set(AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(keyId, secretKey))).withRegion(regions).build());
if (Objects.isNull(res.get())) {
log.warn("connect S3 Server is failure , please check your config param!");
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
return res.get();
} catch (ServiceException | IllegalArgumentException e) {
log.warn("Failed to connect to S3 server e:{}", e.getMessage(), e);
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
}
private String getFileKey(String fileName) {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
return String.format("%s/%s/%s_%s", PREFIX, dateDir, uuid, fileName);
}
DTO
Aws S3 上传后文件响应dto
@EqualsAndHashCode(callSuper = true)
@ToString
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class AwsS3UploadFileResDto extends S3FileInfoDto {
private PutObjectResult s3PutRes;
}
S3 文件 DTO
@ToString
@Data
@NoArgsConstructor
@AllArgsConstructor
public class S3FileInfoDto {
private String fileName;
private String bucketName;
private String fileUrl;
}
AWS S3 预签名响应
@ToString
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class PreUploadRes {
private String key;
private String url;
}
测试
预签名url生成
-
使用postman进行请求后获得url
-
通过生成的预签名url进行上传到S3,返回200则说明文件上传成功了!
-
然后通过CDN映射到S3的域名进行访问,或者直接访问S3,可以查看文件。
其他方法(可以参考着用)
在这里插入代码片
@Slf4j
@Service
public class AwsS3ServiceImpl implements AwsS3Service {
private final ConfigCenter configCenter;
private static final String OPS_PREFIX = "ops";
public AwsS3ServiceImpl(ConfigCenter configCenter) {
this.configCenter = configCenter;
}
@Override
public List<AwsS3UploadFileResDto> uploadFilesToS3(String bucket, List<MultipartFile> files) {
log.info("start upload files to s3 files size:{}", files.size());
if (CollUtil.isEmpty(files)) {
log.warn("upload to s3 files is must be nut null!");
throw new ServiceException(ErrorCode.FILE_IS_EMPTY);
}
return files.stream().filter(Objects::nonNull).map(file -> uploadFileToS3(bucket, file)).collect(Collectors.toList());
}
@Override
public PreUploadRes preUploadFile(String prefix) {
PreUploadRes res = new PreUploadRes();
try {
Optional<List<GpLandPageConfigDto>> s3config = configCenter.getDataWithType2(GpLandPageConstant.CONFIG_KEY, GpLandPageConfigDto.class);
s3config.flatMap(configs -> configs.stream().findFirst()).ifPresent(config -> {
AmazonS3 amazonS3 = s3client();
String fastFileName = getFileKey(prefix);
DateTime expiration = DateUtil.offsetHour(new Date(), 1);
URL url = amazonS3.generatePresignedUrl(new GeneratePresignedUrlRequest(config.getS3Bucket(), fastFileName).withExpiration(expiration).withMethod(HttpMethod.PUT));
res.setKey(config.getCdnPrefix() + "/" + fastFileName).setUrl(url.toString());
log.info("Generate preUrl Request is success :{}", JSONUtil.toJsonStr(res));
});
} catch (Exception e) {
log.error("Generate preUrl Request is failure :{}", e.getMessage(), e);
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
return res;
}
@Override
public AwsS3UploadFileResDto uploadFileToS3(String bucket, MultipartFile file) {
String fastFileName = getFileKey(file.getOriginalFilename());
try {
PutObjectRequest request = new PutObjectRequest(bucket, fastFileName, file.getInputStream(), null);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(file.getContentType());
request.setMetadata(metadata);
PutObjectResult putObjectResult = s3client().putObject(request);
GpLandPageConfigDto config = getConfig();
String url = config.getCdnPrefix() + "/" + fastFileName;
log.info("upload to s3 bucket:{} file:{} url:{} is success ! ===> putRes:{}", bucket, fastFileName, url, JSONUtil.toJsonStr(putObjectResult));
AwsS3UploadFileResDto awsS3UploadFileResDto = new AwsS3UploadFileResDto().setS3PutRes(putObjectResult);
awsS3UploadFileResDto.setFileName(fastFileName);
awsS3UploadFileResDto.setBucketName(bucket);
awsS3UploadFileResDto.setFileUrl(url);
return awsS3UploadFileResDto;
} catch (Exception e) {
log.error("upload original file:{}, fastFileName:{} to S3 is Error:{}", file.getName(), fastFileName, e.getMessage());
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
}
private GpLandPageConfigDto getConfig() {
GpLandPageConfigDto landPageConfigDto = new GpLandPageConfigDto();
configCenter.getDataWithType2(GpLandPageConstant.CONFIG_KEY, GpLandPageConfigDto.class).flatMap(configs -> configs.stream().findFirst()).ifPresent(config -> BeanUtil.copyProperties(config, landPageConfigDto));
if (StringUtils.isBlank(landPageConfigDto.getS3Bucket())) {
throw new ServiceException(ErrorCode.CONFIG_CENTER_CONFIG_EMPTY);
}
return landPageConfigDto;
}
public AmazonS3 s3client() {
try {
AtomicReference<AmazonS3> res = new AtomicReference<>();
Optional<List<GpLandPageConfigDto>> s3config = configCenter.getDataWithType2(GpLandPageConstant.CONFIG_KEY, GpLandPageConfigDto.class);
s3config.flatMap(configs -> configs.stream().findFirst()).ifPresent(config -> {
Regions regions = Regions.fromName(config.getRegions());
res.set(AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(config.getS3AccessKeyId(), config.getS3SecretAccessKey()))).withRegion(regions).build());
});
if (Objects.isNull(res.get())) {
log.warn("connect S3 Server is failure , please check your config param!");
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
return res.get();
} catch (ServiceException | IllegalArgumentException e) {
log.warn("Failed to connect to S3 server e:{}", e.getMessage(), e);
throw new ServiceException(ErrorCode.CONNECT_S3_FAILED);
}
}
@Override
public InputStream downloadFile(String bucketName, String fileKey) {
AmazonS3 s3client = s3client();
GetObjectRequest request = new GetObjectRequest(bucketName, fileKey);
S3Object response = s3client.getObject(request);
return response.getObjectContent();
}
@Override
public void deleteFile(String bucketName, String fileKey) {
log.info("delete S3 file bucketName:{}, fileKey:{}", bucketName, fileKey);
AmazonS3 s3client = s3client();
DeleteObjectRequest request = new DeleteObjectRequest(bucketName, fileKey);
s3client.deleteObject(request);
}
@Override
public void deleteFiles(String bucketName, List<String> fileKeys) {
if (StringUtils.isBlank(bucketName) || CollUtil.isEmpty(fileKeys)) {
log.warn("bucketName or fileKeys");
}
AmazonS3 s3client = s3client();
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(StringUtils.join(fileKeys, ","));
DeleteObjectsResult deleteObjectsResult = s3client.deleteObjects(deleteObjectsRequest);
log.info("S3 deleteObjectsResult:{}", JSONUtil.toJsonStr(deleteObjectsResult));
}
@Override
public List<Bucket> listFile() {
AmazonS3 s3client = s3client();
ListBucketsRequest request = new ListBucketsRequest();
return s3client.listBuckets(request);
}
@Override
public boolean isExistBucket(String bucketName) {
AmazonS3 s3client = s3client();
try {
HeadBucketRequest request = new HeadBucketRequest(bucketName);
s3client.headBucket(request);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public void createBucket(String bucketName) {
boolean isBucketExists = isExistBucket(bucketName);
AmazonS3 s3client;
if (!isBucketExists) {
s3client = s3client();
CreateBucketRequest request = new CreateBucketRequest(bucketName);
s3client.createBucket(request);
}
}
@Override
public void deleteBucket(String bucketName) {
AmazonS3 s3client = s3client();
DeleteBucketRequest request = new DeleteBucketRequest(bucketName);
s3client.deleteBucket(request);
}
@Override
public boolean isExistFileKey(String bucketName, String fileKey) {
AmazonS3 s3client = s3client();
GetObjectRequest request = new GetObjectRequest(bucketName, fileKey);
S3Object response = s3client.getObject(request);
return response != null && fileKey.equals(response.getKey());
}
@Override
public String getUrlFor7Day(String bucketName, String fileKey) {
GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName, fileKey);
DateTime offset = DateUtil.offsetDay(new Date(), 7);
urlRequest.setExpiration(offset);
urlRequest.setMethod(HttpMethod.GET);
URL url = s3client().generatePresignedUrl(urlRequest);
return url.toString();
}
@Override
public String getFileKey(String fileName) {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
return String.format("%s/%s/%s_%s", OPS_PREFIX, dateDir, uuid, fileName);
}
@Override
public S3FileInfoDto getFileInfoByUrl(String url) {
String urlPreFix = url.substring(url.indexOf("//") + 2);
GpLandPageConfigDto config = getConfig();
String bucket = config.getS3Bucket();
String fileName = urlPreFix.substring(urlPreFix.indexOf('/') + 1);
return new S3FileInfoDto(fileName, bucket, url);
}
}