标签: java-http-client

使用 JDK 11 HttpClient 进行代理身份验证

我正在尝试使用 JDK 11 HttpClient通过需要通过登录名和密码进行身份验证的公司代理发出请求。根据JDK的介绍,我正在通过以下方式构建客户端实例:

HttpClient httpClient = HttpClient.newBuilder()
        .version(HTTP_1_1)
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.mycompany.com", 3128)))
        .authenticator(authenticator)
        .build();
Run Code Online (Sandbox Code Playgroud)

,哪里authenticator是:

Authenticator authenticator = new Authenticator() {
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("login", "password".toCharArray());
  }
};
Run Code Online (Sandbox Code Playgroud)

然后我执行请求本身:

HttpRequest outRequest = HttpRequest.newBuilder()
        .version(HTTP_1_1)
        .GET()
        .uri(URI.create("https://httpwg.org/asset/http.svg")) // no matter which URI to request
        .build();
HttpResponse<String> inResponse = httpClient.send(outRequest, BodyHandlers.ofString());
Run Code Online (Sandbox Code Playgroud)

但是,我收到的不是来自目标服务器 ( https://httpwg.org )的有效响应,而是HTTP 407(需要代理身份验证),即HttpClient不使用提供的authenticator.

我已经尝试了这里这里提到的各种解决方案,但没有一个有帮助。

使它工作的正确方法是什么?

java http-proxy java-http-client java-11

8
推荐指数
2
解决办法
3989
查看次数

JDK11 HttpClient 支持预告片标头吗?

我看到 JDK9 中支持预告片(该HttpResponse.trailers\xe2\x80\x8b()方法),但在 JDK 10 上不再支持(该HttpResponse.trailers\xe2\x80\x8b()方法不存在)。

\n

我目前正在使用 JDK11,当我尝试我的请求时:

\n
HttpRequest request = HttpRequest.newBuilder()\n                                 .uri(uri)\n                                 .GET()\n                                 .build();\n\n\nHttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());\n
Run Code Online (Sandbox Code Playgroud)\n

我面对一个java.util.concurrent.ExecutionException: java.io.IOException: no statuscode in response. 仅当我请求带有预告片标题的页面时,它才会失败。\n欢迎任何帮助。谢谢

\n

java java-http-client java-11

8
推荐指数
0
解决办法
265
查看次数

如何使用 Java 的 HttpClient 在慢速流响应主体上超时

当我需要以流方式处理响应时,我应该如何处理使用 Java 11 中包含的 HTTP 客户端挂起发送 HTTP 响应正文的服务器?

已经阅读文档,我知道,这是可以设置在连接超时在请求超时

HttpClient httpClient = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(2))
        .build();

HttpRequest httpRequest = HttpRequest.newBuilder(URI.create("http://example.com"))
        .timeout(Duration.ofSeconds(5))
        .build();

HttpResponse<Stream<String>> httpResponse = httpClient
        .send(httpRequest, HttpResponse.BodyHandlers.ofLines());

Stream<String> responseLineStream = httpResponse.body();
responseLineStream.count();
Run Code Online (Sandbox Code Playgroud)

在上面的代码中:

  • 如果在 2 秒内无法建立连接,则会抛出超时异常。
  • 如果在 5 秒内没有收到响应,则会抛出超时异常。通过实验,定时器在连接建立后启动,对于这种类型BodyHandler,当收到状态行和报头时,就认为收到了响应。

这意味着当代码执行时,在 7 秒内要么抛出异常,要么到达最后一行。但是,最后一行不受任何超时的限制。如果服务器停止发送响应正文,最后一行将永远阻塞。

在这种情况下,如何防止最后一行挂起?

java http java-http-client java-11

8
推荐指数
2
解决办法
265
查看次数

如何抑制"使用孵化模块"编译器警告?

如果发生任何编译器警告,我希望我的构建中断,所以我启用了-Werror.稍后我决定使用Java 9 HttpClient,这是一个孵化模块.不幸的是,我现在得到以下编译器警告:

using incubating module(s): jdk.incubator.httpclient
Run Code Online (Sandbox Code Playgroud)

有没有办法在-Werror不打破构建的情况下同时使用孵化模块?理想情况下,我想完全抑制这个警告.

我正在使用Maven来构建我的项目,所以理想情况下答案应该提供一个示例,说明如何将孵化模块作为Maven项目的一部分进行编译.

java compiler-warnings maven java-9 java-http-client

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

如何在Java http客户端中自定义"主机"头

这是我的代码:

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://127.0.0.1:8081/"))
    .header("Host", "test.example.com")
    .build();
client.send(request, HttpResponse.BodyHandlers.ofString());
Run Code Online (Sandbox Code Playgroud)

结果我看到上面的代码发送:

GET / HTTP/1.1
Connection: Upgrade, HTTP2-Settings
Content-Length: 0
Host: 127.0.0.1:8081
HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
Upgrade: h2c
User-Agent: Java-http-client/10
Host: test.example.com
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它会发送两个Host标头(URI和我指定的Host标头),但我希望它发送我指定的标头,而不是URI中的标头.这个客户有可能吗?

编辑:在Java 11中,它变得更糟(你需要将client.send行改为:)client.send(request, HttpResponse.BodyHandlers.ofString());:

java.lang.IllegalArgumentException: restricted header name: "Host"
Run Code Online (Sandbox Code Playgroud)

如何自定义该标头(测试虚拟主机所需)?

我也试过setHeader并得到完全相同的问题(双头Host或异常).

编辑:我报告了一个JDK错误.

java http2 java-10 java-http-client java-11

7
推荐指数
1
解决办法
1822
查看次数

Java HTTP 客户端是否处理压缩

我试图在新的 Java HTTP 客户端中找到任何关于压缩处理的提及,但失败了。是否有内置配置来处理例如gzipdeflate压缩?

我希望有一个BodyHandler例如这样的东西:

HttpResponse.BodyHandlers.ofGzipped(HttpResponse.BodyHandlers.ofString())
Run Code Online (Sandbox Code Playgroud)

但我没有看到。我也没有看到任何配置HttpClient。我是不是找错地方了,还是故意没有实现并推迟支持库?

java java-http-client java-11

7
推荐指数
3
解决办法
4224
查看次数

在Java 11中HttpClient如何解决受限制的头名:Date

以下java 11代码:

HttpRequest request = HttpRequest.newBuilder()
            .uri(uri)
            .header("Digest", digest)
            .header("Date", date)  
            .build();
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: restricted header name: "Date"
Run Code Online (Sandbox Code Playgroud)

问题是摘要是基于日期的,所以我不能简单地依赖于http客户端日期,因为这会使摘要无效.我需要一种方法来设置Date标头,或者检索Date标头,然后设置摘要.标准java 11似乎都不可能.

java http java-http-client java-11

7
推荐指数
1
解决办法
282
查看次数

如何使用Java 11 HTTP Client为POST请求定义多个参数

我有一个对特定端点发出POST请求的代码。这段代码是使用Apache的HttpClient,我想开始使用HttpClientJava(JDK11)的本机代码。但是我不明白如何指定请求的参数。

这是我使用Apache Httpclient的代码:

var path = Path.of("file.txt");
var entity = MultipartEntityBuilder.create()
            .addPart("file", new FileBody(path.toFile()))
            .addTextBody("token", "<any-token>")
            .build();
Run Code Online (Sandbox Code Playgroud)

和代码使用HttpClient

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
                         .uri(URI.create("https://myendpoint.com/"))
                         .POST( /* How can I set the parameters here? */ );
Run Code Online (Sandbox Code Playgroud)

如何设置filetoken参数?

java multipart java-http-client java-11

7
推荐指数
1
解决办法
602
查看次数

使用 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.HttpClient 上有连接池的处理吗?

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

java api connection-pooling java-http-client

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