java - 使用 SAS URL 为 Azure Blob 上传文件失败
问题描述
我想使用为 blob 生成的 SAS URL 将文件上传到 Azure Blob,但执行 URL 时失败。我收到带有消息的 HTTP 错误 400
未指定此请求所必需的 HTTP 标头。
这是我的代码:
BlobServiceClient blobServiceClient = initBlobStorageClient();
BlobContainerClient testprovenanceContainer = getContainerClient(blobServiceClient, "testcontainer");
BlobClient blobClient = testprovenanceContainer.getBlobClient("hello.png");
OffsetDateTime expiryTime = OffsetDateTime.now().plusMinutes(5);
BlobContainerSasPermission permission = new BlobContainerSasPermission().setAddPermission(true).setWritePermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
String s = "https://testazure.blob.core.windows.net/testcontainer/hello.png?"+blobClient.generateSas(values);
uploadFileWithUrl(new File("hello.png"), new URL(a));
public static void uploadFileWithUrl(File file, URL url) throws IOException {
String contentType = Files.probeContentType(file.toPath());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-type", contentType);
connection.setRequestProperty("User-Agent", "Multi-Cloud Management 006b8507-b815-47b9-bce0-08b91981f17a");
DataOutputStream out = new DataOutputStream (connection.getOutputStream());
out.write(Files.readAllBytes(Paths.get(file.toURI())));
out.close();
// Check the HTTP response code. To complete the upload and make the object available,
// you must interact with the connection object in some way.
connection.getResponseCode();
System.out.println("HTTP response code: " + connection.getResponseCode());
connection.disconnect();
}
解决方案
当我们使用 Azure Blob rest api 使用 sas 令牌将内容上传到 Azure blob 存储时,我们需要x-ms-blob-type
在请求标头中指定。更多详细信息,请参阅文档。现在您将图像上传到 Azure blob,我们可以将BlockBlob
其用作其值。
例如 1. 安装 SDK
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.6.0</version>
</dependency>
- 代码
String accountName="blobstorage0516";
String accountKey ="";
StorageSharedKeyCredential creds = new StorageSharedKeyCredential(accountName,accountKey);
String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net", accountName);
BlobServiceClient blobServiceClient =new BlobServiceClientBuilder()
.endpoint(endpoint)
.credential(creds)
.buildClient();
BlobContainerClient blobContainerClient =blobServiceClient.getBlobContainerClient("test");
BlobClient blobClient= blobContainerClient.getBlobClient("Hello.png");
// set sas permissions
BlobSasPermission permission = new BlobSasPermission().setCreatePermission(true).setWritePermission(true).setReadPermission(true);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(OffsetDateTime.now().plusDays(1), permission)
.setStartTime(OffsetDateTime.now().minusMinutes(5));
// create sas token for the blob
String sas = blobClient.generateSas(values);
//get the blob url
String uri =blobClient.getBlobUrl() +"?" +sas;
URL url = null;
File file = new File("D:\\download\\test.png");
String contentType= null;
DataOutputStream out=null;
HttpURLConnection connection = null;
try {
contentType= Files.probeContentType(file.toPath());
url =new URL (uri);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-type", contentType);
connection.setRequestProperty("x-ms-blob-type","BlockBlob");
out = new DataOutputStream (connection.getOutputStream());
out.write(Files.readAllBytes(Paths.get(file.toURI())));
System.out.println(connection.getResponseCode());
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
out.close();
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
推荐阅读
- asp.net-core - 通过 aspnet 核心中的代码触发 HealthCheck
- django - 从Django中的数据库中填充外键字段的输入字段
- php - 为我在 PHP 中的登录添加另一个“角色”
- haskell - 将混合(可能是 Applicative)类型的参数应用于函数的最佳方法
- javascript - 如何检测用于创建 slug 的输入语言,如果不是英语,则 slug 输入使用 javascript 保持为空
- apache - 使用apache和nestjs重定向到主页的问题
- javascript - 有没有办法从 mongodb 检索数据作为键值映射,其中键是字段的值(使用 Mongoose)
- laravel - Laravel - 如何使用 external_user_id 发送 OneSignal 通知
- bash - Bash 脚本无法从列表中下载源包
- android - 从 Fabric 迁移到 FirebaseCrashlytics 后测试失败