这是第一次针对文件以及对象存储的使用,写个案例,设计如有不妥之处,多多指教
首先,我们引入依赖包
<dependency>
<groupId>com.amazonawsgroupId>
<artifactId>aws-java-sdkartifactId>
<version>1.11.136version>
dependency>
<dependency>
<groupId>com.github.junrargroupId>
<artifactId>junrarartifactId>
<version>4.0.0version>
dependency>
import com.amazonaws.ClientConfigurationFactory;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.*;;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.s3.transfer.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
/**
* @ClassName S3AutoConfiguration
* @Desc S3配置
* @Author Fyf
* @Date 2020/3/13 9:29
* @Version 1.0
**/
@Lazy
@Component
public class S3Util {
AmazonS3 s3;
TransferManager tm;
String bucketName; // 你 bucket 的名字 首先需要保证 s3 上已经存在该存储桶
public S3Util() {
this.s3 = new AmazonS3Client(new BasicAWSCredentials("access_key", "secret_key")
, new ClientConfigurationFactory().getConfig().withSocketTimeout(31000));
s3.setRegion(Region.getRegion(Regions.US_EAST_2));
tm = new TransferManager(s3);
this.bucketName = "ezblock";
}
public String upload(String fileName, InputStream fileStream, ObjectMetadata objectMetadata) {
s3.putObject(new PutObjectRequest(bucketName, fileName, fileStream, objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName, fileName);
URL url = s3.generatePresignedUrl(urlRequest);
return String.valueOf(url);
}
/**
* @param filePath 文件夹名称
* @param file 要上传的文件
* @description:
* @author: Fyf
* @time: 2020/3/16 10:16
* @return:
*/
public void uploadFile(String filePath, String fileName, File file) {
s3.putObject(new PutObjectRequest(bucketName + "/" + filePath, fileName, file)
.withCannedAcl(CannedAccessControlList.PublicRead));
}
/**
* @param dirName 新建文集夹名称 / 唯一标识
* @param directory 本地文件夹路径
* @description: 上传文件夹(异步)
* @author: Fyf
* @time: 2020/3/17 11:15
*/
public MultipleFileUpload uploadDir(String dirName, File directory) {
boolean includeSubdirectoryies = true;
MultipleFileUpload upload = tm.uploadDirectory(bucketName, dirName, directory, includeSubdirectoryies);
return upload;
}
}
@Transactional
@PostMapping(value="/product",consumes = "multipart/form-data")
public Object uploadProduct(@RequestParam("name") String name,
@RequestParam("type") String type,
@RequestPart("file") MultipartFile file) throws IOException {
File destDir = null;
Archive archive = null;
try {
archive = new Archive(file.getInputStream());
// 生成唯一标识
String dirName =TokenUtil.createToken();
destDir = new File( System.getProperties().getProperty("user.home")+ File.separator +dirName);
FileOutputStream fos = null;
FileHeader fileHeader = archive.nextFileHeader();
File destFileName = null;
// 解压文件写入到本地
while (fileHeader != null) {
String compressFileName = fileHeader.getFileNameString().trim();
destFileName = new File(destDir.getAbsolutePath() + "/" + compressFileName);
if (fileHeader.isDirectory()) {
if (!destFileName.exists()) {
destFileName.mkdirs();
}
fileHeader = archive.nextFileHeader();
continue;
}
if (!destFileName.getParentFile().exists()) {
destFileName.getParentFile().mkdirs();
}
fos = new FileOutputStream(destFileName);
archive.extractFile(fileHeader, fos);
fos.close();
fileHeader = archive.nextFileHeader();
}
// upload to s3
MultipleFileUpload upload = s3.uploadDir(dirName , destDir);
// 等待上传完成(阻塞) 这是为了防止异步上传时,我们在接口最后删除了文件夹,导致删除失败
upload.waitForCompletion();
// 生成数据
int iret = productMapper.insert(new EzblockProduct(0,name,type,"",dirName,String.valueOf(System.currentTimeMillis())));
return ResponseUtil.checkSucessful(iret,"上传产品失败");
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
log.produce("V1","Product", ExceptionLogUtils.logMessage(e,this.getClass()));
return ResponseUtil.failure(CodeStatus.FAIL,"上传产品失败");
}finally {
if (archive!=null){
archive.close();
}
if (destDir!=null){
// 删除生成的文件夹
FileUtil.deleteAllFilesOfDir(destDir);
}
}
}
@FeignClient(value = "provider-member")
@RequestMapping("/api/web/v2")
public interface ProductClient {
@PostMapping(value="/product",consumes = "multipart/form-data")
Object uploadProduct(@RequestParam("name") String name,
@RequestParam("type") String type,
@RequestPart("file") MultipartFile file);
}
@RestController
public class ProductController {
@Autowired
ProductClient productClient;
/**
* @description: 上传产品 包含文件
* @author: Fyf
* @time: 2020/3/16 17:54
* @return:
*/
@PostMapping("/upload/product")
public Object upload(@RequestParam("name") String name,
@RequestParam("type") String type,
@RequestParam("file") MultipartFile file){
return productClient.uploadProduct(name,type,file);
}
}