Java-阿里云OSS-文件存储

115 阅读2分钟

配置

获取到你OSS的key、secret、访问路径和桶的名称 注意要设置访问权限

后端接口

  /**
   * 上传资源
   * upload resource
   *
   * @param file 资源文件
   * @return resource file
   */
  @PostMapping("/upload")
  public ResponseEntity<?> uploadResource(@RequestParam MultipartFile file) throws IOException {
    String OriginalFilename = file.getOriginalFilename();
    String FileName = UUID.randomUUID().toString() + OriginalFilename.substring(OriginalFilename.lastIndexOf("."));
    Map<String, String> upload = AlibabaOSSUtils.upload(FileName, file.getInputStream());
    Resources resources = new Resources();
    resources.setUsername(upload.get("fileName"));
    resources.setStorageAddress(upload.get("url"));
    resources.setUploadType(upload.get("fileExtension"));
    resourcesService.insertResources(resources);
    return ResponseEntity.ok(resources.getStorageAddress());
  }

后端工具类

package com.ljc.backendsystem.Utils;


import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.ljc.backendsystem.exception.FileException;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 阿里云OSS工具类
 *
 * @author LJCheng
 */
public class AlibabaOSSUtils {

  public static String ENDPOINT = "oss-cn-guangzhou.aliyuncs.com";
  public static String ACCESS_KEY_ID = "your_Key";
  public static String ACCESS_KEY_SECRET = "your_secret";
  public static String BUCKET_NAME = "your_bucketname";
  public static String[] WHITELIST = {"jpg", "jpeg", "png", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "mp4", "avi", "mov", "webp"};

  public static Map<String, String> TYPE_LOAD = new HashMap<String, String>() {
    {
      put("jpg", "image/jpeg/");
      put("jpeg", "image/jpeg/");
      put("png", "image/png/");
      put("pdf", "application/pdf/");
      put("doc", "application/msword/");
      put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document/");
      put("xls", "application/vnd.ms-excel/");
      put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet/");
      put("ppt", "application/vnd.ms-powerpoint/");
      put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation/");
      put("mp4", "video/mp4/");
      put("avi", "video/x-msvideo/");
      put("mov", "video/quicktime/");
      put("webp", "image/webp/");
    }
  };

  /**
   * 上传文件
   * upload file
   *
   * @param fileName        文件名
   * @param fileInputStream 文件输入流
   * @return 返回文件信息
   */
  public static Map<String, String> upload(String fileName, InputStream fileInputStream) {
    String fileExtension = getFileExtension(fileName);
    if (!isAllowedFormat(fileExtension)) {
      throw new IllegalArgumentException(FileException.INVALID_FILE_FORMAT.getMessageCN());
    }
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    // 通过类型获取路径
    String type = TYPE_LOAD.get(fileExtension);
    String newFileLocation = type + fileName;
    Map<String, String> result = new HashMap<>();
    try {
      // 创建PutObjectRequest对象。
      PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, newFileLocation, fileInputStream);
      ossClient.putObject(putObjectRequest);
      String url = "https://" + BUCKET_NAME + "." + ENDPOINT + "/" + fileName;
      result.put("url", newFileLocation);
      result.put("fileExtension", fileExtension);
      result.put("fileName", fileName);
    } catch (Exception e) {
      handleUploadException(e);
    } finally {
      if (ossClient != null) {
        ossClient.shutdown();
      }
    }
    return result;
  }

  /**
   * 下载文件
   * download file
   *
   * @param fileName  文件名
   * @param cloudLoad 云端路径
   * @param pathName  路径名
   * @return 返回文件信息
   */
  public static Map<String, String> download(String fileName, String cloudLoad, String pathName) {
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    Map<String, String> result = new HashMap<>();

    try {
      // 下载Object到本地文件,并保存到指定的本地路径中。如果指定的本地文件存在会覆盖,不存在则新建。
      // 如果未指定本地路径,则下载后的文件默认保存到示例程序所属项目对应本地路径中。
      ossClient.getObject(new GetObjectRequest(BUCKET_NAME, cloudLoad), new File(pathName + "\\" + fileName));
    } catch (OSSException oe) {
      System.out.println("Caught an OSSException, which means your request made it to OSS, "
          + "but was rejected with an error response for some reason.");
      System.out.println("Error Message:" + oe.getErrorMessage());
      System.out.println("Error Code:" + oe.getErrorCode());
      System.out.println("Request ID:" + oe.getRequestId());
      System.out.println("Host ID:" + oe.getHostId());
    } catch (ClientException ce) {
      System.out.println("Caught an ClientException, which means the client encountered "
          + "a serious internal problem while trying to communicate with OSS, "
          + "such as not being able to access the network.");
      System.out.println("Error Message:" + ce.getMessage());
    } finally {
      if (ossClient != null) {
        ossClient.shutdown();
      }
    }
    result.put("fileName", fileName);
    result.put("fileExtension", getFileExtension(fileName));
    result.put("action", fileName + " download");
    return result;
  }

  /**
   * 处理上传文件异常
   * handle upload exception
   *
   * @param e 异常
   */
  private static void handleUploadException(Exception e) {
    // 之前的异常处理逻辑
    FileException error;
    if (e instanceof OSSException ossException) {
      String errorCode = ossException.getErrorCode();
      error = switch (errorCode) {
        case "InvalidFileFormat" -> FileException.INVALID_FILE_FORMAT;
        case "OSSConnectionError" -> FileException.OSS_CONNECTION_ERROR;
        case "FileUploadError" -> FileException.FILE_UPLOAD_ERROR;
        case "FileDownloadError" -> FileException.FILE_DOWNLOAD_ERROR;
        default -> FileException.UNKNOWN_ERROR;
      };
    } else if (e instanceof ClientException) {
      error = FileException.UNKNOWN_ERROR; // 或者根据ClientException的类型细分错误
    } else {
      error = FileException.UNKNOWN_ERROR;
    }
    throw new RuntimeException("Error code: " + error.getCode() + ", Error message: " + error.getMessageEN(), e);
  }

  /**
   * 获取文件后缀名
   * get file
   *
   * @param fileName 文件名
   * @return 文件后缀名
   */
  private static String getFileExtension(String fileName) {
    int lastDotIndex = fileName.lastIndexOf('.');
    if (lastDotIndex == -1) {
      return "";
    }
    return fileName.substring(lastDotIndex + 1);
  }

  /**
   * 校验文件格式是否在白名单中
   *
   * @param fileExtension 文件后缀名
   * @return 是否在白名单中
   */
  private static boolean isAllowedFormat(String fileExtension) {
    for (String format : WHITELIST) {
      if (format.equalsIgnoreCase(fileExtension)) {
        return true;
      }
    }
    return false;
  }

}