【问题标题】:Url to download file from GCS bucket still accessible after deleting using Java使用 Java 删除后仍可访问从 GCS 存储桶下载文件的 URL
【发布时间】:2023-04-15 22:50:01
【问题描述】:

所以我在从 GCS 存储桶中删除文件时遇到问题,我使用 java 创建文件,代码如下:

public void upload(String projectId, String bucketName, String filePath, String fileName)
  throws IOException, URISyntaxException {

File f = new File(gcsCredDirectory+gcsCredFileName);
if (!f.exists()) {
  f.mkdirs();
}
try(InputStream is = new FileInputStream(f)) {
  StorageOptions storageOptions = StorageOptions.newBuilder()
      .setProjectId(projectId).setCredentials(fromStream(is)).build();
  Storage storage = storageOptions.getService();
  BlobId blobId = BlobId.of(bucketName, fileName);
  BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
  Blob result = storage.create(blobInfo, Files.readAllBytes(Paths.get(filePath)));
  URL url = storage.signUrl(blobInfo, MAX_EXPIRED_DATE, TimeUnit.DAYS, SignUrlOption.withV4Signature());
} catch (Exception e) {
  LOGGER.error("ERROR at GoogleCloudStorageServiceImpl.upload cause : ", e);
  throw e;
}

}

创建的代码很顺利,我得到了下载我上传的文件的Url,实际上可以下载文件,但是通过这段代码删除文件后:

public boolean delete(String projectId, String bucketName, String fileName) {
    File f = new File(gcsCredDir+gcsCredFileName);
    if (!f.exists()) {
      f.mkdirs();
    }
    try(InputStream is = new FileInputStream(f)) {
      StorageOptions storageOptions = StorageOptions.newBuilder()
          .setProjectId(projectId)
          .setCredentials(fromStream(is))
          .build();
      boolean result = storageOptions.getService().delete(bucketName, fileName);
      LOGGER.info("Object " + fileName + " was deleted from " + bucketName);
      return result;
    } catch (Exception e) {
      return false;
    }
  }

我可以看到日志Object + fileName + was deleted from + bucketName,但是当我访问Url下载文件时,我仍然可以下载它。我预计下载会失败,因为文件已被删除。

有什么建议吗?

谢谢

【问题讨论】:

    标签: java google-cloud-platform google-cloud-storage bucket


    【解决方案1】:

    Google 有自己的缓存,可在您删除上传的内容后将其存储一段时间。您需要在上传时使用标头覆盖设置。设置Cache-Control: max-age=0, no-cache。您还可以指定publicprivate

    • public 表示中间服务器可以缓存结果(以获得更快的响应时间)。
    • private 表示只有请求的客户端可以缓存响应,而不是中间服务器。这通常设置为使客户端能够在每次发出请求时获取新副本。

    为了尝试强制缓存删除数据,一些服务器接受PURGE 请求。这些可以通过curl -vv -X PURGE http(s)://example.com/path/to/resource发出

    编辑:

    您可以使用 gsutil 设置缓存控制标头:https://cloud.google.com/storage/docs/gsutil/addlhelp/WorkingWithObjectMetadata

    【讨论】:

    • 感谢您的回答!现在就试试吧:D,顺便说一句,你知道缓存能持续多久吗?谢谢
    • 我不记得我的头顶,但它被设置为存储桶对象的元数据的一部分。如果您真的需要帮助,我会挖掘一些东西,但是这些信息 + 选择的搜索引擎应该足以解决您在缓存结果方面遇到的任何问题。
    • 你好,我试图挖掘设置缓存控制和无缓存的java库,似乎没有找到合适的变量,请问如何通过java设置缓存控制和无缓存?谢谢...
    • 还是必须在bucket中自己设置?