Java 在SpringBoot应用程序中下载时未找到Azure BlobNotFound

Java 在SpringBoot应用程序中下载时未找到Azure BlobNotFound,java,azure,spring-boot,azure-storage-blobs,Java,Azure,Spring Boot,Azure Storage Blobs,我的任务是使用Azure Blob存储从应用程序下载简单的.txt文件。代码应该是有效的。我没有写它,但我觉得它还可以,从我在本文后面将要展示的内容来看,它确实连接到Azure,而且更重要的是,它只有在本地主机上测试应用程序时才有效,而不是在公开可用的站点上 以下是我采取的步骤: 已将文件上载到存储器(带下划线的是其中之一): 为按钮添加了适当的链接,该按钮应通过RESTAPI下载附件 当然,我还添加了对数据库中附件的引用(其ID、名称等) 以下是它在前端的外观: 这就是我得到的: 我在某

我的任务是使用Azure Blob存储从应用程序下载简单的.txt文件。代码应该是有效的。我没有写它,但我觉得它还可以,从我在本文后面将要展示的内容来看,它确实连接到Azure,而且更重要的是,它只有在本地主机上测试应用程序时才有效,而不是在公开可用的站点上

以下是我采取的步骤:

  • 已将文件上载到存储器(带下划线的是其中之一):
  • 为按钮添加了适当的链接,该按钮应通过RESTAPI下载附件
  • 当然,我还添加了对数据库中附件的引用(其ID、名称等)
  • 以下是它在前端的外观:
  • 这就是我得到的:
  • 我在某处看到,这可能是由于Azure CORS设置不允许应用程序访问存储造成的。以下是我迄今为止所做的工作:

  • 转到portal.azure.com并更改了CORS设置,如下所示:
  • 在这个Microsoft链接下找到了一些关于将一些代码放入应用程序的内容,但它不是Java。我想Java中有一些类似的方法: . 在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()
            );
        }
    
    控制器服务类部件:

    @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()
            );
        }
    
    以及AzureBlobStorageArticLeaAttachmentService类:

    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名称是否正确:
    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();
        }
    }
    
    //
    ///将blob下载到内存中
    /// 
    ///blob容器名称
    ///斑点名称
    公共静态ByteArrayOutputStream下载BlobToMemory(字符串containerName,字符串blobName){
    CloudStorageAccount=null;
    CloudBlobContainer容器=null;
    ByteArrayOutputStream ByteArrayOutputStream=null;
    试一试{
    account=CloudStorageAccount.parse(ConnString);
    CloudBlobClient=account.createCloudBlobClient();
    container=client.getContainerReference(containerName);
    container.createIfNotExists();
    CloudBlockBlob CloudBlockBlob=container.getblockblobbreference(blobName);
    byteArrayOutputStream=新建byteArrayOutputStream();
    cloudBlockBlob.download(byteArrayOutputStream);
    }捕获(例外情况除外){
    例如printStackTrace();
    }
    通过tearrayoutputstream返回;
    }
    /// 
    ///将blob下载到本地磁盘
    /// 
    ///blob容器名称
    ///斑点名称
    ///例如:C:\\Test\Test.txt
    publicstaticvoid下载blobtodisk(stringcontainername、stringblobname、stringfilepath){
    CloudStorageAccount=null;
    CloudBlobContainer容器=null;
    试一试{
    account=CloudStorageAccount.parse(ConnString);
    CloudBlobClient=account.createCloudBlobClient();
    container=client.getContainerReference(containerName);
    container.createIfNotExists();
    CloudBlockBlob CloudBlockBlob=container.getblockblobbreference(blobName);
    FileOutputStream FileOutputStream=新的FileOutputStream(filePath);
    cloudBlockBlob.download(fileOutputStream);
    }捕获(例外情况除外){
    例如printStackTrace();
    }
    }
    
    当我设法找到正确的申请地址时,Lee Liu关于Blob名称的建议是正确的。原来,用户可以看到的域名地址以“azureedge.net”结尾,但当我进入portal.azure.com时,有一个不同的域名。这是主要问题的根源。在那之后,我确实发现了存储中正确的Blob名称的问题-因为
    String.format
    ,我不得不在数据库中添加带有“u”符号的ID,然后开始下载内容,而不是空文件。
    代码似乎还可以,这是地址和文件名不正确的问题。

    您可以展示一些关于如何下载blob的代码吗?当然可以。我已经编辑了这篇文章,并在问题的结尾部分添加了代码