Java URIBuilder 在加载程序的未命名模块中 'app'

Java URIBuilder are in unnamed module of loader 'app'

我想执行 GET 请求:

    HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
    URIBuilder uriBuilder = new URIBuilder(request.getURI())
            .addParameter("code", "001")
            .addParameter("name", "AAA")
           

    String auth = user + ":" + mdp;

    byte[] encodedAuth = Base64.encodeBase64(
            auth.getBytes(StandardCharsets.ISO_8859_1));

    String authHeader = "Basic " + new String(encodedAuth);

    request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute((HttpUriRequest) uriBuilder);

    int statusCode = response.getStatusLine().getStatusCode();

当我尝试捕获我的 HTTPResponse 时 client.execute((HttpUriRequest) uriBuilder); 我有这个错误:

java.lang.ClassCastException: class org.apache.http.client.utils.URIBuilder cannot be cast to class org.apache.http.client.methods.HttpUriRequest (org.apache.http.client.utils.URIBuilder and org.apache.http.client.methods.HttpUriRequest are in unnamed module of loader 'app')

您遇到错误是因为您试图将 URIBuilder 的实例转换为 HttpUriRequest

您需要创建适当的 HttpUriRequest 实现才能执行您的 HTTP 请求。

在你的用例中,我想它应该是这样的:

    URIBuilder uriBuilder = new URIBuilder(URL_SECURED_BY_BASIC_AUTHENTICATION)
            .addParameter("code", "001")
            .addParameter("name", "AAA");

    URI uri = uriBuilder.build();  
           
    HttpGet request = new HttpGet(uri);

    String auth = user + ":" + mdp;

    byte[] encodedAuth = Base64.encodeBase64(
            auth.getBytes(StandardCharsets.ISO_8859_1));

    String authHeader = "Basic " + new String(encodedAuth);

    request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(request);

    int statusCode = response.getStatusLine().getStatusCode();

您的评论似乎是您正在尝试使用 SSL 连接到站点:问题是您的 Java 代码不信任服务器。

您需要配置有效的证书链并指示您的代码使用它才能解决问题。

Apache 客户端不依赖标准的 JSSE 机制来实现此目的。相反,您需要使用适当的 TrustManager 配置 SSLContext。请查看以下代码(第一部分来自 Android 开发者站点中的 this extraordinary documentation fragment):

// Load your server certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");

InputStream input = new BufferedInputStream(
  new FileInputStream("server.crt")
);

Certificate certificate;
try {
  certificate = cf.generateCertificate(input);
} finally {
  input.close();
}

// Create an in-memory KeyStore containing the server certificate
// It is required in order to configure the TrustManager
String keyStoreType = KeyStore.getDefaultType(); // JKS
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("cert", certificate);

// Create a TrustManager that trusts the server certificates in the KeyStore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
  TrustManagerFactory.getDefaultAlgorithm()
);
trustManagerFactory.init(keyStore);

// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManagerFactory.getTrustManagers(), null);

// Now, the actual Apache Client part

//Create a SSLConnectionSocketFactory and pass it the above created SSLContext
SSLConnectionSocketFactory factory = 
  new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier()
);

//Create the actual HttpClient
CloseableHttpClient client = HttpClients
  .custom()
  .setSSLSocketFactory(factory)
  .build()
;

// Use this client to perform your HTTP invocation

HttpResponse response = client.execute(request);

int statusCode = response.getStatusLine().getStatusCode();

您可以通过浏览器或openssl等工具获取服务器证书。请看这个很棒的 SO question.