【问题标题】:Azure BlobNotFound when downloading in SpringBoot app在 SpringBoot 应用程序中下载时 Azure BlobNotFound
【发布时间】:2019-01-01 23:11:18
【问题描述】:

我的任务是使用 Azure Blob 存储从应用程序下载简单的 .txt 文件。该代码应该可以工作。这不是我写的,但它看起来不错localhost,但不在公开网站上。

这些是我做的步骤:

  1. 上传文件到存储(下划线为其中之一):
  2. 为应该通过 REST API 下载附件的按钮添加了正确的链接
  3. 当然,我还在数据库中添加了对附件的引用(其 ID、名称等)
  4. 这是它在前端的外观:
  5. 这就是我得到的:

我在某处看到它可能是由不允许应用访问存储的 Azure CORS 设置引起的。这是我到目前为止所做的:

  1. 访问了 portal.azure.com 并更改了 CORS 设置,如下所示:
  2. 在此 Microsoft 链接下发现了一些关于将一些代码放入应用程序的信息,但它不是 Java。我猜Java中有一些类比的方法: https://blogs.msdn.microsoft.com/windowsazurestorage/2014/02/03/windows-azure-storage-introducing-cors/ 。在 Azure 门户中添加 CORS 规则后是否需要?

另外,我发现它可能是由存储访问权限引起的。公共访问级别设置为容器:

不确定它是否提供任何东西,但这些是容器的属性:

我收到的BlobNotFound 错误还有什么问题?希望我在这里提供了足够的信息,但如果需要更多信息,请在评论中说,我会提供。

这是应该下载此方法附件的代码,包含在 3 个类中:

控制器类部分:

@GetMapping("/download/{id}")
    @ResponseStatus(HttpStatus.OK)
    public void downloadAttachment(@PathVariable long id, HttpServletResponse response) throws IOException {
       dataUploadRequestAttachmentService.downloadStaticAttachment(response, id);
    }

控制器服务类部分:

public void downloadStaticAttachment(HttpServletResponse response, long id) throws IOException {
        ArticleAttachment articleAttachment = this.findAttachment(id);
        String mimeType = URLConnection.guessContentTypeFromName(articleAttachment.getName());

        if (mimeType == null){
            mimeType = "application/octet-stream";
        }

        response.setContentType(mimeType);
        response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", articleAttachment.getName()));

        azureBlobStorageArticleAttachmentService.downloadArticleAttachment(
                articleAttachment.getName(),
                articleAttachment.getId(),
                response.getOutputStream()
        );
    }

还有 AzureBlobStorageArticleAttachmentService 类:

public void downloadArticleAttachment(String attachmentName, Long articleId, OutputStream outputStream) {
        try {
            CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));
            blob.download(outputStream);
        } catch (URISyntaxException | StorageException e) {
            e.printStackTrace();
            log.error(String.format("Download article attachment %s error", attachmentName));
        }
    }

【问题讨论】:

  • 您能否展示一些有关如何下载 blob 的代码?
  • 当然。我已经编辑了帖子并将代码添加到问题的末尾部分

标签: java azure spring-boot azure-blob-storage


【解决方案1】:

根据您的描述,请调试检查是否在代码中得到正确的blob名称:CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));

这是一个关于如何使用 Java SDK 下载 blob 的演示供您参考:

/// <summary>
/// download blob to memory
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
public static ByteArrayOutputStream downloadBlobToMemory(String containerName, String blobName) {
    CloudStorageAccount account = null;
    CloudBlobContainer container = null;
    ByteArrayOutputStream byteArrayOutputStream = null;
    try {
        account = CloudStorageAccount.parse(ConnString);
        CloudBlobClient client = account.createCloudBlobClient();
        container = client.getContainerReference(containerName);
        container.createIfNotExists();
        CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);         

        byteArrayOutputStream=new ByteArrayOutputStream();
        cloudBlockBlob.download(byteArrayOutputStream);         

    }catch(Exception ex) {
        ex.printStackTrace();
    }

    return byteArrayOutputStream;
}


/// <summary>
/// download blob to local disk
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
/// <param name="filePath"> for example: C:\\Test\test.txt</param>
public static void downloadBlobToDisk(String containerName, String blobName, String filePath) {
    CloudStorageAccount account = null;
    CloudBlobContainer container = null;
    try {
        account = CloudStorageAccount.parse(ConnString);
        CloudBlobClient client = account.createCloudBlobClient();
        container = client.getContainerReference(containerName);
        container.createIfNotExists();
        CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
        FileOutputStream fileOutputStream=new FileOutputStream(filePath);
        cloudBlockBlob.download(fileOutputStream);
    }catch(Exception ex) {
        ex.printStackTrace();
    }
}

【讨论】:

    【解决方案2】:

    当我设法找到正确的应用程序地址时,Lee Liu 关于 Blob 名称的建议是正确的。原来,用户可见的域地址以“azureedge.net”结尾,但是当我进入portal.azure.com 时却有不同的地址。它导致了主要问题。在那之后,我确实发现了存储中正确的 Blob 名称的问题 - 因为String.format,我不得不在数据库中添加他们的 ID 并带有“_”符号,然后他们开始下载内容而不是空文件。 代码好像没问题,是地址和文件名不正确的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-19
      • 2023-01-19
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      相关资源
      最近更新 更多