适用于 blob 的 Azure Java SDK - 已请求加载默认 HttpClient 提供程序,但在类路径中找不到该提供程序

Posted

技术标签:

【中文标题】适用于 blob 的 Azure Java SDK - 已请求加载默认 HttpClient 提供程序,但在类路径中找不到该提供程序【英文标题】:Azure Java SDK for blob - A request was made to load the default HttpClient provider but one could not be found on the classpath 【发布时间】:2021-03-16 00:27:13 【问题描述】:

跟随https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-java?tabs=powershell 得到这个错误:

Caused by: java.lang.IllegalStateException: A request was made to load the default HttpClient provider but one could not be found on the classpath. If you are using a dependency manager, consider including a dependency on azure-core-http-netty or azure-core-http-okhttp. Depending on your existing dependencies, you have the choice of Netty or OkHttp implementations. Additionally, refer to https://aka.ms/azsdk/java/docs/custom-httpclient to learn about writing your own implementation.
at com.azure.core.implementation.http.HttpClientProviders.createInstance(HttpClientProviders.java:37)
at com.azure.core.http.HttpClient.createDefault(HttpClient.java:27)
at com.azure.core.http.HttpPipelineBuilder.build(HttpPipelineBuilder.java:60)
at com.azure.storage.blob.implementation.util.BuilderHelper.buildPipeline(BuilderHelper.java:110)
at com.azure.storage.blob.BlobServiceClientBuilder.buildAsyncClient(BlobServiceClientBuilder.java:107)
at com.azure.storage.blob.BlobServiceClientBuilder.buildClient(BlobServiceClientBuilder.java:84)

【问题讨论】:

错误抛出:BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint("azuremlexamples.blob.core.windows.net").buildClient(); 【参考方案1】:

找不到 HttpClient 时会出现error。它似乎与代码无关。尝试检查您是否按照文档中的步骤进行操作。

我在 App.java 中尝试了以下代码,效果很好。

StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(endpoint).credential(credential).buildClient();

如果删除credential(),会返回这个错误:ResourceNotFound 指定的资源不存在

无需凭据即可访问公共 blob:

【讨论】:

azuremlexamples.blob.core.windows.net/datasets/iris.csv 是公开的,所以我想在没有凭据的情况下访问 我也尝试在没有凭据的情况下访问公共 blob,它也可以。我编辑回复以添加屏幕截图。请分享您遵循的步骤,最好分享您的代码。【参考方案2】:

有效:

采取https://github.com/Azure-Samples/azure-sdk-for-java-storage-blob-upload-download

将 pom 中的 azure 版本更改为 12.9

导出 AZURE_STORAGE_ACCOUNT=azuremlexamples

如下编辑

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.common.StorageSharedKeyCredential;

public class Quickstart 
    static File createTempFile() throws IOException 

        // Here we are creating a temporary file to use for download and upload to Blob
        // storage
        File sampleFile = null;
        sampleFile = File.createTempFile("sampleFile", ".txt");
        System.out.println(">> Creating a sample file at: " + sampleFile.toString());
        Writer output = new BufferedWriter(new FileWriter(sampleFile));
        output.write("Hello Azure Storage blob quickstart.");
        output.close();

        return sampleFile;
    

    public static void main(String[] args) throws IOException 

        // Creating a sample file to use in the sample
        File sampleFile = null;
        sampleFile = createTempFile();
        String downloadedFilePath = "downloadedFile.txt";

        // Retrieve the credentials and initialize SharedKeyCredentials
        String accountName = System.getenv("AZURE_STORAGE_ACCOUNT");
        String accountKey = System.getenv("AZURE_STORAGE_ACCESS_KEY");
        String endpoint = "https://" + accountName + ".blob.core.windows.net";
        String containerName = "datasets";
        String blobName = "iris.csv";

        // Create a SharedKeyCredential
        //StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);
       
        // Create a blobServiceClient
        BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
            .endpoint(endpoint)
            .buildClient();

        // Create a containerClient
        BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(containerName);

        // Create a container
//        blobServiceClient.createBlobContainer(containerName);
  //      System.out.printf("Creating a container : %s %n", blobContainerClient.getBlobContainerUrl());

        // Create a BlobClient to run operations on Blobs
    //    BlobClient blobClient = blobContainerClient.getBlobClient(blobName);

                System.out.println("Listing blobs in the container: " + blobContainerClient.getBlobContainerUrl());
                blobContainerClient.listBlobs()
                        .forEach(
                            blobItem -> System.out.println("This is the blob name: " + blobItem.getName()));
        
    

运行 mvn compile exec:java

输出是:

列出容器中的 blob:https://azuremlexamples.blob.core.windows.net/datasets 这是 blob 名称:criteo-uplift-v2.1.csv.gz 这是 blob 名称:iris.csv

【讨论】:

以上是关于适用于 blob 的 Azure Java SDK - 已请求加载默认 HttpClient 提供程序,但在类路径中找不到该提供程序的主要内容,如果未能解决你的问题,请参考以下文章

使用 Blob 服务客户端查找 azure 帐户密钥失败(azure python sdk)

Azure.Cosmos 还是 Microsoft.Azure.Cosmos、Azure.Storage.Blob 还是 Microsoft.Azure.Storage.Blob?适用于 .NET C

未从 blob 上的 azure java sdk 收到元数据字段

如何确定 Azure Defender 适用于哪些 blob?

使用 Azure Java SDK V12 和 ListBlobs() 在 Azure Blobstorage 中列出 Blob 非常慢

在 Java SDK 中模拟 Azure 存储 Blob