赞
踩
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.126</version>
</dependency>
package test.s3; import com.amazonaws.ClientConfiguration; import com.amazonaws.Protocol; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.io.InputStream; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class AmazonS3Util { /** * S3服务器地址 */ private final static String S3_URL = ""; /** * 账号key */ private final static String ACCESS_KEY = ""; /** * 密码key */ private final static String SECRET_KEY = ""; /** * 存放合并信息集合 如果服务是集群或多活部署,需改成redis存储 */ private final static Map<String, Map<String, Object>> uploadIdMap = new ConcurrentHashMap<>(); private static Logger logger = LoggerFactory.getLogger(AmazonS3Util.class); /** * 获取连接 * @return * @throws Exception */ public static AmazonS3 connectS3Client() throws Exception { URL url = new URL(S3_URL); ClientConfiguration config = new ClientConfiguration().withProtocol(Protocol.HTTP); AmazonS3 client = AmazonS3ClientBuilder.standard() .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(url.toString(),Regions.CN_NORTH_1.toString())) .withClientConfiguration(config) .withPathStyleAccessEnabled(true) .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY))) .build(); return client; } /** * 上传文件 * @param upload * @return * @throws Exception */ public static void uploadFile(Upload upload) throws Exception { AmazonS3 s3client = connectS3Client(); InputStream inputStream = null; try { String fileKey = getFileKey(upload.getMultipartFile().getOriginalFilename()); inputStream = upload.getMultipartFile().getInputStream(); PutObjectRequest request = new PutObjectRequest(upload.getBucketName(), fileKey, inputStream,null); s3client.putObject(request); } catch (Exception e) { throw e; } finally { if (inputStream != null) { try { inputStream.close(); } catch (Exception e) { throw e; } } } } /** * 分段上传文件 * @param upload * @return * @throws Exception */ public static String mutilpartUpload(Upload upload) throws Exception { logger.info("开始上传"); AmazonS3 s3client = connectS3Client(); InputStream inputStream = null; try { String fileKey = null; String uploadId = null; List<PartETag> partETagList = new ArrayList<>(); Map<String, Object> result = uploadIdMap.get(upload.getIdentifier()); if (result == null) { fileKey = getFileKey(upload.getMultipartFile().getOriginalFilename()); InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(upload.getBucketName(), fileKey); InitiateMultipartUploadResult initResponse = s3client.initiateMultipartUpload(initRequest); uploadId = initResponse.getUploadId(); result = new HashMap<>(); result.put("uploadId", uploadId); result.put("partETagList", partETagList); result.put("fileKey", fileKey); } else { uploadId = result.get("uploadId").toString(); partETagList = (List<PartETag>) result.get("partETagList"); fileKey = result.get("fileKey").toString(); } // 分段上传 inputStream = upload.getMultipartFile().getInputStream(); UploadPartRequest uploadRequest = new UploadPartRequest() .withBucketName(upload.getBucketName()) .withKey(fileKey) .withUploadId(uploadId) .withPartNumber(upload.getChunkNumber()) .withInputStream(inputStream) .withPartSize(upload.getMultipartFile().getSize()); UploadPartResult uploadResult = s3client.uploadPart(uploadRequest); partETagList.add(uploadResult.getPartETag()); logger.info("上传完成: upload.getTotalChunks():{}, upload.getChunkNumber():{}", upload.getTotalChunks(), upload.getChunkNumber()); if (upload.getTotalChunks() == upload.getChunkNumber()) { logger.info("开始合并"); CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(upload.getBucketName(), fileKey, uploadId, partETagList); s3client.completeMultipartUpload(compRequest); // 删除map数据 uploadIdMap.remove(upload.getIdentifier()); } else { // 更新map数据 uploadIdMap.put(upload.getIdentifier(), result); } return fileKey; } catch (Exception e) { throw e; } finally { if (inputStream != null) { try { inputStream.close(); } catch (Exception e) { throw e; } } } } /** * 下载 * @param bucketName * @param fileKey * @return * @throws Exception */ public static InputStream downloadFile(String bucketName, String fileKey) throws Exception{ AmazonS3 s3client = connectS3Client(); GetObjectRequest request = new GetObjectRequest(bucketName, fileKey); S3Object response = s3client.getObject(request); InputStream input = response.getObjectContent(); return input; } /** * 删除文件 * @param bucketName * @param fileKey * @throws Exception */ public static void deleteFile(String bucketName, String fileKey) throws Exception { AmazonS3 s3client = connectS3Client(); DeleteObjectRequest request = new DeleteObjectRequest(bucketName, fileKey); s3client.deleteObject(request); } /** * Bucket列表 * @return * @throws Exception */ public static List<Bucket> listFile() throws Exception{ AmazonS3 s3client = connectS3Client(); ListBucketsRequest request = new ListBucketsRequest(); List<Bucket> list = s3client.listBuckets(request); return list; } /** * 是否存在Bucket * @param bucketName * @return * @throws Exception */ public static boolean isExistBucket(String bucketName) throws Exception{ AmazonS3 s3client = connectS3Client(); try { HeadBucketRequest request = new HeadBucketRequest(bucketName); s3client.headBucket(request); } catch (Exception e) { return false; } return true; } /** * 创建Bucket * @param bucketName * @return * @throws Exception */ public static void createBucket(String bucketName) throws Exception{ boolean isBucketExists = isExistBucket(bucketName); AmazonS3 s3client = null; if (!isBucketExists) { s3client = connectS3Client(); CreateBucketRequest request = new CreateBucketRequest(bucketName); s3client.createBucket(request); } } /** * 删除Bucket * @param bucketName * @return * @throws Exception */ public static void deleteBucket(String bucketName) throws Exception { AmazonS3 s3client = connectS3Client(); DeleteBucketRequest request = new DeleteBucketRequest(bucketName); s3client.deleteBucket(request); } /** * fileKey是否存在 * @param bucketName * @param fileKey * @return * @throws Exception */ public static boolean isExistFileKey(String bucketName, String fileKey) throws Exception{ AmazonS3 s3client = connectS3Client(); GetObjectRequest request = new GetObjectRequest(bucketName,fileKey); S3Object response = s3client.getObject(request); boolean result = response != null && fileKey.equals(response.getKey()); return result; } /** * 获取文件key * @param fileName * @return * @throws Exception */ private static String getFileKey(String fileName) throws Exception{ String uuid = UUID.randomUUID().toString().replaceAll("-",""); String dateDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); String fileKey = dateDir + "/" + uuid + "/" + fileName; return fileKey; } }
package test.s3; import org.springframework.web.multipart.MultipartFile; public class Upload { /** * 桶名称 */ private String bucketName; /** * 总块数 */ private int totalChunks; /** * 当前块数,从1开始 */ private int chunkNumber; /** * 上传id,每个文件唯一 */ private String identifier; /** * 上传文件信息, 需手动赋值 */ private MultipartFile multipartFile; public int getTotalChunks() { return totalChunks; } public String getBucketName() { return bucketName; } public void setBucketName(String bucketName) { this.bucketName = bucketName; } public void setTotalChunks(int totalChunks) { this.totalChunks = totalChunks; } public int getChunkNumber() { return chunkNumber; } public void setChunkNumber(int chunkNumber) { this.chunkNumber = chunkNumber; } public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; } public MultipartFile getMultipartFile() { return multipartFile; } public void setMultipartFile(MultipartFile multipartFile) { this.multipartFile = multipartFile; } }
package test.s3; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; @RestController @RequestMapping("/s3") public class FileS3Controller { @ApiOperation("上传") @RequestMapping(method = RequestMethod.POST, value = "/upload") public String upload(Upload upload, MultipartFile file) throws Exception { upload.setMultipartFile(file); return AmazonS3Util.mutilpartUpload(upload); } @ApiOperation("下载") @RequestMapping(method = RequestMethod.GET, value = "/download") public void download(String bucketName, String fileKey, String fileName, HttpServletResponse response) throws Exception { InputStream inputStream = AmazonS3Util.downloadFile(bucketName, fileKey); response.setContentType( "application/x-msdownload"); fileName = new String(fileName.getBytes("gbk"), "iso8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); ServletOutputStream out = response.getOutputStream(); byte[] bffer = new byte[1024]; int r = 0; while ((r = inputStream.read(bffer, 0, 1024)) != -1) { out.write(bffer, 0, r); } try { inputStream.close(); } catch (Exception e) { e.printStackTrace(); } try { out.close(); } catch (Exception e) { e.printStackTrace(); } } @ApiOperation("删除") @RequestMapping(value = "/delete", method = RequestMethod.GET) public String delete(String bucketName, String fileKey) throws Exception { AmazonS3Util.deleteFile(bucketName, fileKey); return "删除成功"; } }
npm install vue-simple-uploader --save
import Vue from 'vue'
import App from './App.vue'
import uploader from 'vue-simple-uploader'
Vue.config.productionTip = false
Vue.use(uploader)
new Vue({
render: h => h(App),
}).$mount('#app')
<template> <uploader :options="options" class="uploader-example"> <uploader-unsupport></uploader-unsupport> <uploader-drop> <p>Drop files here to upload or</p> <uploader-btn>select files</uploader-btn> <uploader-btn :attrs="attrs">select images</uploader-btn> <uploader-btn :directory="true">select folder</uploader-btn> </uploader-drop> <uploader-list></uploader-list> </uploader> </template> <script> export default { data () { return { options: { target: '//localhost:8082/s3/upload', query: { // 格外参数 bucketName: 'test' }, chunkSize: 10*1024*1024, // 分块大小 forceChunkSize: true, // 是否强制所有的块都是小于等于 chunkSize 的值。默认是 false simultaneousUploads: 1, // 并发上传数,默认 3 maxChunkRetries: 3, // 最大自动失败重试上传次数,值可以是任意正整数,如果是 undefined 则代表无限次,默认 0 testChunks: false }, attrs: { accept: 'image/*' } } } } </script> <style> .uploader-example { width: 880px; padding: 15px; margin: 40px auto 0; font-size: 12px; box-shadow: 0 0 10px rgba(0, 0, 0, .4); } .uploader-example .uploader-btn { margin-right: 4px; } .uploader-example .uploader-list { max-height: 440px; overflow: auto; overflow-x: hidden; overflow-y: auto; } </style>
1、以上代码不支持并发上传。并发上传后续再研究解决
2、如果服务是多活部署(集群部署),AmazonS3Util 工具类里的uploadIdMap要换成redis存储
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。