赞
踩
1、引入pom
- <dependency>
- <groupId>software.amazon.awssdk</groupId>
- <artifactId>s3</artifactId>
- <version>2.16.60</version>
- </dependency>
2、yml添加aws配置信息
- aws:
- accessKeyId: "8MIPOASDIOI9J45J"
- secretAccessKey: "dzWkljdfhjkne87+Jlkejerk7ujkjsU"
- endpointUrl: "https://s3.demo.com:8088"
3、增加aws初始化配置类
- @Configuration
- public class AwsS3Config {
- @Value("aws.accessKeyId")
- private String accessKeyId;
-
- @Value("aws.secretAccessKey")
- private String secretAccessKey;
-
- @Value("aws.endpointUrl")
- private String endpointUrl;
-
- private static final Region region = Region.US_EAST_1;
-
- @Bean
- public S3Client s3Client(){
- AwsBasicCredentials awsBasicCredentials = AwsBasicCredentials.create(accessKeyId, secretAccessKey);
- S3Configuration s3Config = S3Configuration.builder().pathStyleAccessEnabled(true).build();
- try{
- S3Client s3 = S3Client.builder()
- .endpointOverride(new URI(endpointUrl))
- .credentialsProvider(StaticCredentialsProvider.create(awsBasicCredentials))
- .region(region)
- .serviceConfiguration(s3Config)
- .build();
-
- return s3;
- } catch (URISyntaxException e){
- throw new RuntimeException(e.getMessage());
- }
- }
-
- @Bean
- public S3Presigner s3Presigner(){
- try{
- S3Configuration s3Config = S3Configuration.builder().pathStyleAccessEnabled(true).build();
- S3Presigner presigner = S3Presigner.builder()
- .endpointOverride(new URI(endpointUrl))
- .region(region)
- .build();
-
- return presigner;
- } catch (URISyntaxException e){
- throw new RuntimeException(e.getMessage());
- }
- }
- }
3、实现对象列表、异步对象上传、对象下载、对象删除
- @Resource
- private S3Client s3Client;
-
- @Resource
- private S3Presigner s3Presigner;
-
- /**
- * 对象列表
- * @param bucket bucket
- * @param key 对象路径
- * @param pageToken 下一页token
- * @param pageSize 分页大小
- */
- public ResultBean list(String bucket, String key, String pageToken, Integer pageSize) throws UnsupportedEncodingException {
- if(StringUtil.isEmpty(bucket)) return ResultUtil.resultFail("参数错误");
-
- ListObjectsV2Request.Builder builder = ListObjectsV2Request.builder();
- // 设置bucket
- builder.bucket(bucket);
- // 设置一次请求返回多少数据
- builder.maxKeys(pageSize);
- if(StringUtil.isNotEmpty(key)) {
- // 设置文件路径分隔符,用于查找
- builder.prefix(key).delimiter("/");
- }
-
- ListObjectsV2Request listObjReq = builder.build();
- ListObjectsV2Response listObjRes = s3Client.listObjectsV2(listObjReq);
-
- // 获取下一页数据
- if(listObjRes.isTruncated() && StringUtil.isNotEmpty(pageToken)){
- listObjReq = listObjReq.toBuilder().continuationToken(pageToken).build();
- listObjRes = s3Client.listObjectsV2(listObjReq);
- }
-
- List<S3Object> s3ObjectList = listObjRes.contents();
- // 获取下一页token
- String pageNextToken = listObjRes.nextContinuationToken();
- String finalPageNextToken = StringUtil.isEmpty(pageNextToken) ? "" : URLEncoder.encode(pageNextToken, "utf-8");
- // 重新组装为自己需要的数据格式
- List<AwsS3ObjectVO> s3ObjList = Lists.transform(s3ObjectList, (s3Object) -> {
- AwsS3ObjectVO vo = new AwsS3ObjectVO();
- vo.setBucket(bucket);
- vo.setKey(s3Object.key());
- vo.setSize(FileUtil.calSize(s3Object.size()));
- vo.setStorageClass(s3Object.storageClassAsString());
- vo.setLastModified(DateUtil.dataToStr(s3Object.lastModified(), "yyyy-MM-dd HH:mm:ss"));
- vo.setPageToken(finalPageNextToken);
-
- return vo;
- });
-
- return ResultUtil.resultSuccess(s3ObjList);
- }
-
- /**
- * 对象上传
- * @param bucket bucket
- * @param file 文件对象
- */
- public ResultBean upload(String bucket, MultipartFile file){
- if(StringUtil.isEmpty(bucket) || file.isEmpty()) return ResultUtil.resultFail("参数错误");
-
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
- String fileName = UUID.randomUUID().toString().trim().replaceAll("-", "");
- String filePath = sdf.format(new Date()) + "/" + fileName;
- try{
- ResultBean resultBean = singleUpload(bucket, filePath, file);
- if(resultBean.getCode().equals("-1")) return ResultUtil.resultFail(resultBean.getMsg());
-
- return ResultUtil.resultSuccess(filePath);
- } catch (Exception ex){
- throw new BizException(ex.getMessage(), ex);
- }
- }
-
- /**
- * 异步完整上传不分片
- * @param bucket bucket
- * @param key 对象路径
- * @param file 文件对象
- */
- @Async("awsThreadPoolExecutor")
- ResultBean singleUpload(String bucket, String key, MultipartFile file) throws IOException {
- Long startTime = System.currentTimeMillis() / 1000;
- PutObjectRequest putObjectRequest = PutObjectRequest.builder()
- .bucket(bucket)
- .key(key)
- .build();
- RequestBody requestBody = RequestBody.fromInputStream(file.getInputStream(), file.getSize());
- PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, requestBody);
- SdkHttpResponse sdkHttpResponse = putObjectResponse.sdkHttpResponse();
- if(!sdkHttpResponse.isSuccessful()){
- return ResultUtil.resultFail("上传对象存储失败, statusCode:" + sdkHttpResponse.statusCode() + "statusText:" + sdkHttpResponse.statusText());
- }
- long endTime = System.currentTimeMillis() / 1000;
- log.info("上传文件(" + key + ")总计耗费时间为:" + (endTime - startTime) + " 秒");
-
- return ResultUtil.resultSuccess();
- }
-
- /**
- * 对象下载,返回url下载地址
- * @param bucket bucket
- * @param key 对象路径
- */
- public ResultBean download(String bucket, String key){
- if(StringUtil.isEmpty(bucket) || StringUtil.isEmpty(key)) return ResultUtil.resultFail("参数错误");
-
- GetObjectRequest objectRequest = GetObjectRequest.builder().bucket(bucket).key(key).build();
- GetObjectPresignRequest objectPresignRequest = GetObjectPresignRequest.builder()
- .signatureDuration(Duration.ofMinutes(10))
- .getObjectRequest(objectRequest)
- .build();
- PresignedGetObjectRequest presignedGetObjectRequest = s3Presigner.presignGetObject(objectPresignRequest);
- String url = presignedGetObjectRequest.url().toString();
-
- return ResultUtil.resultSuccess(url);
- }
-
- /**
- * 对象删除,支持批量删除
- * @param bucket bucket
- * @param keyList 多个key组成的json数组转化成list对象
- */
- public ResultBean delete(String bucket, List<AwsS3ObjectVO> keyList){
- if(keyList == null || keyList.size() <= 0) return ResultUtil.resultFail("参数错误");
-
- List<ObjectIdentifier> identifierList = new ArrayList<>();
- for(AwsS3ObjectVO vo : keyList){
- identifierList.add(ObjectIdentifier.builder().key(vo.getKey()).build());
- }
-
- try{
- Delete delete = Delete.builder().objects(identifierList).build();
- DeleteObjectsRequest deleteObjectRequest = DeleteObjectsRequest.builder().bucket(bucket).delete(delete).build();
- s3Client.deleteObjects(deleteObjectRequest);
-
- return ResultUtil.resultSuccess();
- } catch (Exception ex){
- throw new BizException(ex.getMessage(), ex);
- }
- }
4、对象存储线程池配置,上传文件时用到
- /**
- * 对象存储线程池配置类
- */
- @EnableAsync
- @Configuration
- public class ThreadPoolConfig {
-
- @Bean("awsThreadPoolExecutor")
- public ThreadPoolTaskExecutor awsThreadPoolExecutor(){
- // cpu参数
- int cpuCount = Runtime.getRuntime().availableProcessors();
- ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
- // 核心线程数
- taskExecutor.setCorePoolSize(cpuCount);
- // 最大线程数
- taskExecutor.setMaxPoolSize(cpuCount * 2);
- // 任务队列容量
- taskExecutor.setQueueCapacity(128);
- // 空闲队列存活时间
- taskExecutor.setKeepAliveSeconds(20);
- // 线程前缀
- taskExecutor.setThreadNamePrefix("awsTaskExecutor-");
- // 拒绝策略
- taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
- // 任务完成后自动关闭线程池
- taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
- // 初始化
- taskExecutor.initialize();
-
- return taskExecutor;
- }
- }
工具类ResultUtil、ResultBean和ResultPageInfo(分页需引入谷歌的pagehelper插件)
- public class ResultUtil {
- /**
- * 分页查询成功
- */
- public static <T> ResultPageInfo<T> pageSuccess(List<T> list){
- ResultPageInfo<T> bean = new ResultPageInfo();
- if(CollectionUtils.isEmpty(list)){
- bean.setCurrentPage(0);
- bean.setPageSize(0);
- bean.setData(list);
- bean.setTotalCount(0);
- bean.setCode("0");
- bean.setMsg("success");
- } else {
- PageInfo<T> page = new PageInfo<T>(list);
- bean.setCurrentPage(page.getPageNum());
- bean.setPageSize(page.getPageSize());
- bean.setData(page.getList());
- bean.setTotalCount(Integer.parseInt(page.getTotal() + ""));
- bean.setTotalPage(page.getPages());
- bean.setCode("0");
- bean.setMsg("success");
- }
-
- return bean;
- }
-
- /**
- * 操作成功
- */
- public static <T> ResultBean<T> resultSuccess(T t){
- ResultBean<T> resultBean = new ResultBean();
- resultBean.setCode("0");
- resultBean.setMsg("success");
- resultBean.setData(t);
-
- return resultBean;
- }
-
- /**
- * 操作成功
- */
- public static <T> ResultBean<T> resultSuccess(){
- ResultBean<T> resultBean = new ResultBean();
- resultBean.setCode("0");
- resultBean.setMsg("success");
-
- return resultBean;
- }
-
- /**
- * 操作失败
- */
- public static <T> ResultBean<T> resultFail(String errMsg){
- ResultBean<T> resultBean = new ResultBean();
- resultBean.setCode("-1");
- resultBean.setMsg(errMsg);
-
- return resultBean;
- }
- }
- @Data
- public class ResultBean<T> implements Serializable {
-
- private static final long serialVersionUID = 160311355525594862L;
-
- private String code = "0";
-
- private String msg = "success";
-
- private T data;
- }
- /**
- * 返回分页数据
- */
- @Data
- public class ResultPageInfo<T> implements Serializable {
-
- private static final long serialVersionUID = 160311355525522362L;
-
- private String code = "0";
-
- private String msg = "success";
-
- private List<T> data;
-
- /**
- * 分页页码
- */
- private Integer currentPage = 1;
-
- /**
- * 分页大小
- */
- private Integer pageSize;
-
- /**
- * 总页数
- */
- private Integer totalPage;
-
- /**
- * 总记录条数
- */
- private Integer totalCount;
- }
自定义异常类BizException
- /**
- * 业务逻辑通用异常
- */
- public class BizException extends RuntimeException {
- static final long serialVersionUID = -7034897190745766802L;
-
- private String errorCode;
-
- public BizException(String message) {
- super(message);
- }
-
- public BizException(String errorCode, String message) {
- super(message);
- setErrorCode(errorCode);
- }
-
- public BizException(String errorCode, String message, Throwable cause) {
- super(message, cause);
- setErrorCode(errorCode);
- }
-
- public BizException(String errorCode, Throwable cause) {
- super(cause);
- setErrorCode(errorCode);
- }
-
- public String getErrorCode() {
- return errorCode;
- }
-
- public void setErrorCode(String errorCode) {
- this.errorCode = errorCode;
- }
- }
全局异常捕捉类GlobalExceptionHandler
- /**
- * 全局异常捕捉
- */
- @Slf4j
- @RestControllerAdvice
- public class GlobalExceptionHandler {
- /**
- * 默认异常的捕捉
- */
- @ExceptionHandler({Throwable.class})
- public ResultBean exception(Throwable e){
- log.error("系统异常", e);
- return ResultUtil.resultFail(e.getMessage());
- }
-
- /**
- * 自定义业务异常的捕捉
- */
- @ExceptionHandler({BizException.class})
- public ResultBean exception(BizException e){
- log.error("业务异常", e);
- return ResultUtil.resultFail(e.getErrorCode(), e.getMessage());
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。