英文:
Cant generate a download link for a file that exists in virtual directory in azure using spring boot
问题
我有一个容器,其中包含许多虚拟目录,例如:
https://accountName.blob.core.windows.net/containerName/blobName,而 blob 名称是 Azure 上的虚拟目录,比如:number/name/UUID/anotherUUID/file.txt,我尝试下载 file.txt,但每次都会出现以下错误:
<Code>BlobNotFound</Code>
尽管我可以从 Azure 门户使用 SAS 令牌生成下载链接并成功下载文件,但当我从我的 Spring Boot 应用程序内部生成下载链接时,会出现上述错误。
这是上传 blob 的代码:
BlobClient blob = container.getBlobClient(filePath); // 其中文件路径是虚拟目录路径
blob.upload(BinaryData.fromBytes(bytes));
这是下载 blob 的代码:
BlobClient blobClient = blobServiceClient.getBlobContainerClient(containerName)
.getBlobClient(filepath);
OffsetDateTime expiryTime = OffsetDateTime.now()
.plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission).setStartTime(
OffsetDateTime.now());
String sasToken = blobClient.generateSas(values);
String fileUrl = blobClient.getBlobUrl();
StringBuilder stringBuilder = new StringBuilder(fileUrl);
stringBuilder.append(""?"");
String last = stringBuilder.toString();
String result = java.net.URLDecoder.decode(last, StandardCharsets.UTF_8.name());
return result+sasToken;
注意:代码部分不进行翻译。
英文:
i have a container which consists of many virtual directories for example :
https://accountName.blob.core.windows.net/containerName/blobName , and the blob name is a virtual directory on azure let's say for example : number/name/UUID/anotherUUID/file.txt and iam trying to download the file.txt but each time i get the following error :
<Code>BlobNotFound</Code>
although i can generate the download link using sas token from azure portal and get a download link for the file and it is downloaded succesfully , but when i generate the download link from inside my spring boot application i get the error above .
here is the code for uploading a blob :
BlobClient blob = container.getBlobClient(filePath); // where file path is the virutal directory path
blob.upload(BinaryData.fromBytes(bytes));
and here is the code for downloading the blob :
BlobClient blobClient = blobServiceClient.getBlobContainerClient(container name)
.getBlobClient(filepath);
OffsetDateTime expiryTime = OffsetDateTime.now()
.plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission).setStartTime(
OffsetDateTime.now());
String sasToken = blobClient.generateSas(values);
String fileUrl = blobClient.getBlobUrl();
StringBuilder stringBuilder = new StringBuilder(fileUrl);
stringBuilder.append("?");
String last = stringBuilder.toString();
String result = java.net.URLDecoder.decode(last, StandardCharsets.UTF_8.name());
return result+sasToken;
答案1
得分: 1
我已经在我的环境中使用下面的代码重现了您的要求,并得到了预期的结果。请检查它是否有助于解决问题并满足您的需求。
- 确保您的容器具有所需的特权。
在这里,我使用了POST映射来通过REST API调用上传文件。
@PostMapping("/upload")
public String uploadFile(@RequestParam(value = "file") MultipartFile file) throws IOException {
String str = "DefaultEndpointsProtocol=https;AccountName=<your_account_name>;AccountKey=<your_account_key>;EndpointSuffix=core.windows.net";
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
BlobContainerClient container = new BlobContainerClientBuilder().connectionString(str)
.containerName("<your_container_name>").buildClient();
BlobClient blob = container.getBlobClient("ParentDir/"+"ChildDir/"+file.getOriginalFilename());
blob.upload(file.getInputStream(), file.getSize(), true);
String sasToken = blob.generateSas(values);
String result = java.net.URLDecoder.decode(blob.getBlobUrl() + "?", StandardCharsets.UTF_8.name());
return result + sasToken;
}
更新:
在调用BlobClient类时,如果我们将文件名作为参数传递给container.getBlobClient()
,它将在容器内创建文件。要在目录内创建文件,我们必须在container.getBlobClient()
中传递带有/
的目录和文件名,如下所示:
BlobClient blob = container.getBlobClient("ParentDir/"+"ChildDir/"+file.getOriginalFilename());
更新后的输出:
我可以使用生成的URL下载文件,如下所示:
英文:
I have reproduced your requirement in my environment using below code and got expected results. Check if it helps you to fix the issue and achieve your requirement.
- Be sure that your container has the required privileges.
Here, I'm using the post mapping to upload the file via REST API call.
@PostMapping("/upload")
public String uploadFile(@RequestParam(value = "file") MultipartFile file) throws IOException {
String str = "DefaultEndpointsProtocol=https;AccountName=<your_account_name>;AccountKey=<your_account_key>;EndpointSuffix=core.windows.net";
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
BlobContainerClient container = new BlobContainerClientBuilder().connectionString(str)
.containerName("<your_container_name>").buildClient();
BlobClient blob = container.getBlobClient("ParentDir/"+"ChildDir/"+file.getOriginalFilename());
blob.upload(file.getInputStream(), file.getSize(), true);
String sasToken = blob.generateSas(values);
String result = java.net.URLDecoder.decode(blob.getBlobUrl() + "?", StandardCharsets.UTF_8.name());
return result + sasToken;
}
Update:
when calling the BlobClient class, if we pass the filename as parameter in the container.getBlobClient()
, it will create file inside the container.
To create file inside the directory, we have to pass directory with /
along with the filename inside the container.getBlobClient()
as shown below:
BlobClient blob = container.getBlobClient("ParentDir/"+"ChildDir/"+file.getOriginalFilename());
Updated Output:
I could download the file with the generated URL as shown below:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论