0
votes

I would like to upload a file to Azure Blob using a generated SAS URL for the blob but it is failed when I executed the URL. I received HTTP error 400 with the message

An HTTP header that's mandatory for this request is not specified.

Here is my code:

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();
}
1

1 Answers

1
votes

When we use Azure Blob rest api to upload something to Azure blob storage with sas token, We need to specify x-ms-blob-type in request headers. For more details, please refer to the document. Now you upload image to Azure blob, we can use BlockBlob as its value.

For example 1. Install SDK

<dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-storage-blob</artifactId>
      <version>12.6.0</version>
    </dependency>
  1. Code
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();
            }
        }

enter image description here enter image description here