标签: java-http-client

Java9 HttpClient SSLHandshakeException

我试图从Java 9测试新的HttpClient.出于测试目的,我使用的是https://jsonplaceholder.typicode.com提供的api .但是,我收到握手异常,不知道原因.

我正在运行的代码:

 private final String TEST_URI = "https://jsonplaceholder.typicode.com/posts";

    @Test
    public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI(TEST_URI))
                .GET()
                .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandler.asString());
        assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
    }
Run Code Online (Sandbox Code Playgroud)

我收到一个例外:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:198)
    at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:159)
    at java.base/sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1905)
    at java.base/sun.security.ssl.SSLEngineImpl.processInputRecord(SSLEngineImpl.java:1140)
    at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1020)
    at java.base/sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:902)
    at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:680)
    at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:626)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.unwrapBuffer(AsyncSSLDelegate.java:476)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.handshakeReceiveAndUnWrap(AsyncSSLDelegate.java:395)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.doHandshakeImpl(AsyncSSLDelegate.java:294)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.doHandshakeNow(AsyncSSLDelegate.java:262)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.connect(AsyncSSLDelegate.java:233)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLConnection.connect(AsyncSSLConnection.java:78)
    at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.<init>(Http2Connection.java:272)
    at jdk.incubator.httpclient/jdk.incubator.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:108)
    at jdk.incubator.httpclient/jdk.incubator.http.ExchangeImpl.get(ExchangeImpl.java:86)
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.establishExchange(Exchange.java:257) …
Run Code Online (Sandbox Code Playgroud)

java ssl java-9 tls1.2 java-http-client

6
推荐指数
1
解决办法
569
查看次数

使用 Java 11 HttpClient 读取分块数据

我正在尝试使用 Java 11 的 java.net.http.HttpClient 从 Http Response 读取分块数据,但我一次只能获取一行。我需要一次获取一整块。

这是我的代码:

    final InputStream eventStream;

    try {
        HttpResponse<InputStream> httpResponse = httpClient.send(HttpRequest
                .newBuilder(
                        new URI(this.config.getEnvironmentAccess().getUrl() + ":<port>/status/?pretty=true"))
                .GET().build(), BodyHandlers.ofInputStream());

        LOGGER.info("event stream HttpResponse received");
        LOGGER.info("statusCode: {}", httpResponse.statusCode());
        LOGGER.info("headers: {}", httpResponse.headers());
        LOGGER.info("version: {}", httpResponse.version());
        LOGGER.info("request: {}", httpResponse.request());

        eventStream = httpResponse.body();
    } catch (IOException | InterruptedException | URISyntaxException e) {
        throw new RuntimeException("Unable to get status event stream", e);
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(eventStream));
    String line = "";

    try {
        while ((line = br.readLine()) …
Run Code Online (Sandbox Code Playgroud)

java chunked java-http-client java-11

6
推荐指数
1
解决办法
7537
查看次数

不能对 java.net.http.HttpClient 发出多个请求,否则会收到:javax.net.ssl.SSLHandshakeException

我正在测试HttpClientJava 11的新功能并遇到以下行为:

我正在向公共 REST API 发出两个异步请求以进行测试,并使用一个客户端和两个单独的请求进行了尝试。这个过程没有抛出任何异常。

String singleCommentUrl = "https://jsonplaceholder.typicode.com/comments/1";
String commentsUrl = "https://jsonplaceholder.typicode.com/comments";

Consumer<String> handleOneComment = s -> {
    Gson gson = new Gson();
    Comment comment = gson.fromJson(s, Comment.class);
    System.out.println(comment);
};
Consumer<String> handleListOfComments = s -> {
    Gson gson = new Gson();
    Comment[] comments = gson.fromJson(s, Comment[].class);
    List<Comment> commentList = Arrays.asList(comments);
    commentList.forEach(System.out::println);
};

HttpClient client = HttpClient.newBuilder().build();

client.sendAsync(HttpRequest.newBuilder(URI.create(singleCommentUrl)).build(), HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(handleOneComment)
        .join();

client.sendAsync(HttpRequest.newBuilder(URI.create(commentsUrl)).build(), HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(handleListOfComments)
        .join();
Run Code Online (Sandbox Code Playgroud)

然后我尝试将其重构HttpClient为一个方法,当它尝试发出第二个请求时出现以下异常:

public void run() {
    String singleCommentUrl = …
Run Code Online (Sandbox Code Playgroud)

java exception httprequest sslhandshakeexception java-http-client

6
推荐指数
1
解决办法
1332
查看次数

Java 11 HttpClient 中取消 http 请求

我正在尝试通过新的 Java 11 HttpClient 取消 http 请求。

这是我的测试代码:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class App {

    public static void main(String... args) throws InterruptedException {
        HttpClient client = HttpClient.newBuilder().build();

        URI uri = URI.create("http://releases.ubuntu.com/18.04.2/ubuntu-18.04.2-desktop-amd64.iso");
        HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build();

        var bodyHandler = HttpResponse.BodyHandlers.ofByteArrayConsumer(b -> System.out.println("#"));
        var future = client.sendAsync(request, bodyHandler);
        Thread.sleep(1000);

        future.cancel(true);
        System.out.println("\r\n----------CANCEL!!!------------");
        System.out.println("\r\nisCancelled: " + future.isCancelled());
        Thread.sleep(250);
    }
}
Run Code Online (Sandbox Code Playgroud)

future.cancel(true);我预计,该请求任务将在调用行后立即取消。因此,控制台中最后打印的行应该是isCancelled: true

但是,当我运行这段代码时,我看到这样的东西:

#################################################### ####################################################
-  -  -  -  - 取消!!! -  -  -  -  -  - …

java java-http-client

6
推荐指数
1
解决办法
6416
查看次数

java.net.HttpClient 上有连接池的处理吗?

我想使用 Java 11 HttpClient 并使用 HTTP 1.1 的 Keep-Alive 参数在同一地址上发送多个请求。我知道 Apache HTTP 客户端有类似的功能,但是 Java API 客户端有类似的功能吗?

java api connection-pooling java-http-client

6
推荐指数
1
解决办法
3026
查看次数

JAVA-11: java.net.httpClient 如何设置重试?

目前,我正在用JDK-11的新Httporg.apache.http.*库替换现有的http 客户端库。有许多令人兴奋的新功能,但是我没有找到有关“如何在新的 HTTPClient 中设置 RetryRequestHandler”的任何内容。之前的 Apache HttpClient 构建器的代码片段:

    ...
    ...
    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
            .setDefaultRequestConfig(config)
            .setConnectionManager(connectionManager)
    if(retryCount > 0) {
        httpClientBuilder.setRetryHandler(new RetryRequestHandler(retryCount, url));
    }
    if (proxyHost) {
        HttpHost proxy = new HttpHost(proxyHost, proxyPort, "http");
        httpClientBuilder.setProxy(proxy);
    }
    ...
    ...
Run Code Online (Sandbox Code Playgroud)

这里RetryRequestHandler是DefaultHttpRequestRetryHandler的扩展

public class RetryRequestHandler extends DefaultHttpRequestRetryHandler{...} 
Run Code Online (Sandbox Code Playgroud)

java-11 的新 HttpClient 中没有设置重试的选项。有什么解决方法可以这样做吗?

java httpclient java-http-client java-11

5
推荐指数
1
解决办法
5512
查看次数

有没有办法将 java.net.http.HttpClient 与 Oauth2 一起使用?

您好,我从 java 11 切换RestTemplateHttpClientjava 11。我也想从 java 11 切换OAuth2RestTemplateHttpClientjava 11。

我找不到任何有关使用HttpClientOAuth2 的材料。有可能以简单的方式吗?

这是个好主意吗?或者我应该WebClient从春天开始使用?

java httpclient oauth-2.0 java-http-client

5
推荐指数
1
解决办法
2703
查看次数

HttpClient 关闭连接

我想问一下执行后这段代码是否自动关闭连接。此外,如果它失败并崩溃,它还会关闭连接吗?

HttpClient.newHttpClient().send(
    HttpRequest.newBuilder()
        .uri(URI.create("url_website"))
        .timeout(Duration.ofSeconds(5))
        .GET()
        .build(),
    HttpResponse.BodyHandlers.ofString())
.body()
Run Code Online (Sandbox Code Playgroud)

java java-http-client java-11

5
推荐指数
1
解决办法
212
查看次数

定义 java.net.http.HttpClient 实例属性是一个好习惯吗?

我正在使用 JDK HttpClient发出一些异步 HTTP 请求。特别是我有一类类似于以下的类:

public class MyClass {
  private HttpClient client;

  public MyClass(){
    client = HttpClient.newBuilder()
    .version(Version.HTTP_1_1)
    .connectTimeout(Duration.ofSeconds(20))
    .build();
  }
  
  public void send(String url){
    HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(url))
    .header("Content-Type", "application/json")
    .POST(BodyPublishers.ofFile(Paths.get("file.json")))
    .build();
    client.sendAsync(request, BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println); 
  }
}
Run Code Online (Sandbox Code Playgroud)

这样,当调用发送方法时,我将重用客户端属性。根据文档,这是有效的,因为:“一旦构建,HttpClient 就是不可变的,并且可以用于发送多个请求”

除此之外,我还有一个内存缓存,用于保存MyClass的实例。我想知道这是否是一个好的做法。我特别想知道在内存中保留对 HttpClient 客户端属性的引用是否可能会导致任何类型的内存泄漏或问题(如此处提到的问题

例如,这可能是释放/结束用于执行异步请求的线程执行器的问题吗?

java java-http-client

5
推荐指数
0
解决办法
782
查看次数

Java 11/17 HttpClient - 如何尝试一个主机名后面的多个 IP?

我如何配置Java自己的“新”(Java 9/11/17)HttpClient来尝试比主机名后面第一个找到的IP地址更多的内容?有(至少)两种情况:

  1. 支持 IPv4 和 IPv6 的服务器:
> host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1
Run Code Online (Sandbox Code Playgroud)
  1. 一个“逻辑”主机名,其中服务由多个冗余服务器提供:
> host frontend.example.com
frontend.example.com has address 245.3.4.5
frontend.example.com has address 246.4.5.6
frontend.example.com has IPv6 address 4f00:5678::19
frontend.example.com has IPv6 address 4f00:7890::20
Run Code Online (Sandbox Code Playgroud)

我的观察是,HttpClient 仅尝试第一个传递的地址,如果在该地址下无法访问服务,则失败。有没有办法告诉它尝试所有分配的 IP 地址 -InetAddress.getAllByName()传递它们 - 直到可以在其中一个地址找到 HTTP 服务器,并且如果没有一个成功,则仅以“无连接”失败。

在第一种情况下,如果某个服务绑定到 IPv4 或 IPv6 地址,则这是相关的。在第二种情况下,其中一台服务器或服务可能因维护或技术问题而停机,而另一台服务器或服务则服务所有传入请求。因此,在我看来,这应该是 HTTP 客户端实现的一个相当常见的要求。尽管如此,我还不明白如何实现这种行为。

java inetaddress java-http-client java-11 java-17

5
推荐指数
0
解决办法
379
查看次数