我正在尝试使用 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.
我已经尝试了这里和这里提到的各种解决方案,但没有一个有帮助。
使它工作的正确方法是什么?
我看到 JDK9 中支持预告片(该HttpResponse.trailers\xe2\x80\x8b()方法),但在 JDK 10 上不再支持(该HttpResponse.trailers\xe2\x80\x8b()方法不存在)。
我目前正在使用 JDK11,当我尝试我的请求时:
\nHttpRequest request = HttpRequest.newBuilder()\n .uri(uri)\n .GET()\n .build();\n\n\nHttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());\nRun Code Online (Sandbox Code Playgroud)\n我面对一个java.util.concurrent.ExecutionException: java.io.IOException: no statuscode in response. 仅当我请求带有预告片标题的页面时,它才会失败。\n欢迎任何帮助。谢谢
当我需要以流方式处理响应时,我应该如何处理使用 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)
在上面的代码中:
BodyHandler,当收到状态行和报头时,就认为收到了响应。这意味着当代码执行时,在 7 秒内要么抛出异常,要么到达最后一行。但是,最后一行不受任何超时的限制。如果服务器停止发送响应正文,最后一行将永远阻塞。
在这种情况下,如何防止最后一行挂起?
如果发生任何编译器警告,我希望我的构建中断,所以我启用了-Werror.稍后我决定使用Java 9 HttpClient,这是一个孵化模块.不幸的是,我现在得到以下编译器警告:
using incubating module(s): jdk.incubator.httpclient
Run Code Online (Sandbox Code Playgroud)
有没有办法在-Werror不打破构建的情况下同时使用孵化模块?理想情况下,我想完全抑制这个警告.
我正在使用Maven来构建我的项目,所以理想情况下答案应该提供一个示例,说明如何将孵化模块作为Maven项目的一部分进行编译.
这是我的代码:
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 HTTP 客户端中找到任何关于压缩处理的提及,但失败了。是否有内置配置来处理例如gzip或deflate压缩?
我希望有一个BodyHandler例如这样的东西:
HttpResponse.BodyHandlers.ofGzipped(HttpResponse.BodyHandlers.ofString())
Run Code Online (Sandbox Code Playgroud)
但我没有看到。我也没有看到任何配置HttpClient。我是不是找错地方了,还是故意没有实现并推迟支持库?
以下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似乎都不可能.
我有一个对特定端点发出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)
如何设置file和token参数?
我正在尝试使用 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 11 HttpClient 并使用 HTTP 1.1 的 Keep-Alive 参数在同一地址上发送多个请求。我知道 Apache HTTP 客户端有类似的功能,但是 Java API 客户端有类似的功能吗?