Azure Blob错误:StorageException:不满足使用HTTP条件标头指定的条件

问题描述 投票:0回答:1

因此,我有一个功能,每10分钟简单地从blob存储中下载文本并检查结果。此功能可以运行几天。但是它经常(大约每天)失败,然后出现以下错误。

原因:com.microsoft.azure.storage.StorageException:不满足使用HTTP条件标头指定的条件。

我的代码很简单。

public String downloadTextBlob(CloudBlobDirectory dir, String filename) {
    try {
        return dir.getBlockBlobReference(filename).downloadText();
    } catch (StorageException | IOException | URISyntaxException e) {
        throw new WorkbenchRuntimeException(e.getMessage(), e);
    }
}

我在here上发布了相同的问题,并且我对回答有关使用OperationContext修复该问题的答案很感兴趣。但是问题不在Java上,答案也没有真正解释它的实际作用。

这里是建议的解决方案(非Java代码)

 OperationContext context = new OperationContext();
 context.SendingRequest += (sender, e) => { 
     e.Request.Headers["if-match"] = "*";
 };

任何人都可以解释这实际上在做什么吗?也许我可以在Java中复制它,我注意到Java天蓝色存储sdk中有一个OperationContext,并且可以使用操作上下文作为参数来调用.downloadText()。我只是不确定该如何处理OperationContext。

azure http azure-storage azure-storage-blobs azure-java-sdk
1个回答
0
投票

首先,我鼓励您在这里阅读有关Azure Blob存储中的条件标头的信息:https://docs.microsoft.com/en-us/rest/api/storageservices/specifying-conditional-headers-for-blob-service-operations

我尚未查看Java SDK的源代码,但我的猜测是downloadText()操作正在幕后执行多项操作。在第一个操作中,它获取Blob的属性(例如Blob的长度等),而在下一个操作中,它实际上是在下载Blob。作为第一个操作的一部分,它还会获取blob的etag,并将相同的etag传递给if-match标头中的第二个操作。

现在在第一个操作和第二个操作之间,使用blob进行了某些更改,从而导致etag值更改。由于第二个请求仍使用旧的etag值,并且etag之间不匹配,因此您的请求失败,并显示precondition failedif-match标头中存在etag会指示存储服务执行条件匹配(即etag匹配)的操作[[仅在。由于etag不匹配,您将收到此错误。

要解决此问题,您需要使用以下downloadText()方法的替代:

downloadText(final String charsetName, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)

并且为downloadText(final String charsetName, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)指定一个带有“ *”值的访问条件,这实际上告诉存储服务忽略etag值。您可以在此处了解有关访问条件的更多信息:if-match

您的代码将类似于(未经测试的代码):

https://docs.microsoft.com/en-us/java/api/com.microsoft.azure.storage.accesscondition?view=azure-java-legacy

并在您的downloadText()方法中使用此访问条件。    
© www.soinside.com 2019 - 2024. All rights reserved.