这是我的示例代码。查询编码为UTF-8:
initMap([...your respose...])
运行此示例后,我得到以下异常:
HttpRequest request = HttpRequest.newBuilder()
.header("content-type", "application/json;charset=UTF-8")
.uri(URI.create("http://localhost:8080/test?param1=test%C5%84"))
.GET()
.build();
HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build()
.send(request, HttpResponse.BodyHandler.asString(Charset.forName("UTF-8")));
java.lang.IllegalArgumentException: char=324
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.Huffman.codeOf(Huffman.java:559)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.Huffman.lengthOf(Huffman.java:524)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.StringWriter.configure(StringWriter.java:79)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.StringWriter.configure(StringWriter.java:62)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.IndexNameValueWriter.value(IndexNameValueWriter.java:64)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.Encoder.literal(Encoder.java:422)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.Encoder.header(Encoder.java:245)
at jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.Encoder.header(Encoder.java:198)
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.encodeHeadersImpl(Http2Connection.java:927)
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.encodeHeaders(Http2Connection.java:878)
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.encodeHeaders(Http2Connection.java:951)
at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.sendFrame(Http2Connection.java:984)
at jdk.incubator.httpclient/jdk.incubator.http.Stream.sendHeadersAsync(Stream.java:547)
at jdk.incubator.httpclient/jdk.incubator.http.Exchange.lambda$responseAsyncImpl0$8(Exchange.java:322)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SSLFlowDelegate.setALPN(SSLFlowDelegate.java:164)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SSLFlowDelegate.access$200(SSLFlowDelegate.java:81)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:340)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:215)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$TryEndDeferredCompleter.complete(SequentialScheduler.java:315)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SSLFlowDelegate$Reader.incoming(SSLFlowDelegate.java:242)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SubscriberWrapper.incomingCaller(SubscriberWrapper.java:388)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SubscriberWrapper.onNext(SubscriberWrapper.java:343)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SubscriberWrapper.onNext(SubscriberWrapper.java:58)
at jdk.incubator.httpclient/jdk.incubator.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:739)
at jdk.incubator.httpclient/jdk.incubator.http.SocketTube$SocketFlowTask.run(SocketTube.java:171)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:271)
at jdk.incubator.httpclient/jdk.incubator.http.internal.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:224)
at jdk.incubator.httpclient/jdk.incubator.http.SocketTube$InternalReadPublisher$InternalReadSubscription.signalReadable(SocketTube.java:675)
at jdk.incubator.httpclient/jdk.incubator.http.SocketTube$InternalReadPublisher$ReadEvent.signalEvent(SocketTube.java:829)
at jdk.incubator.httpclient/jdk.incubator.http.SocketTube$SocketFlowEvent.handle(SocketTube.java:243)
at jdk.incubator.httpclient/jdk.incubator.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:769)
at jdk.incubator.httpclient/jdk.incubator.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:731)
表示从查询中解码char=324
当我读取堆栈跟踪时,我在类中找到了ń
这个方法:
jdk.incubator.http.Stream<T>
在此方法中,private void setPseudoHeaderFields() {
HttpHeadersImpl hdrs = requestPseudoHeaders;
String method = request.method();
hdrs.setHeader(":method", method);
URI uri = request.uri();
hdrs.setHeader(":scheme", uri.getScheme());
// TODO: userinfo deprecated. Needs to be removed
hdrs.setHeader(":authority", uri.getAuthority());
// TODO: ensure header names beginning with : not in user headers
String query = uri.getQuery();
String path = uri.getPath();
if (path == null || path.isEmpty()) {
if (method.equalsIgnoreCase("OPTIONS")) {
path = "*";
} else {
path = "/";
}
}
if (query != null) {
path += "?" + query;
}
hdrs.setHeader(":path", path);
}
用于为我们提供已解码的查询并导致上述异常。
当我在调试模式下使用uri.getQuery()
时(它给了我们编码的查询)一切都很顺利。
我的问题是:这是一个错误还是故意使用?如果它不是错误,我该如何避免异常?
答案 0 :(得分:13)
这是一个错误:
使用某些UTF-8字符时,使用jdk.incubator.httpclientjava.lang.IllegalArgumentException
某些UTF-8字符如“š”不能与HttpClient一起使用。然而 像“å”这样的其他人可以。
请参阅:https://bugs.openjdk.java.net/browse/JDK-8201238
Java 9/10 HttpClient 孵育。它没有生产就绪。它在包名中非常清楚地说明了这一点。因此,它很可能包含错误。
它将作为currently scheduled for release 25th September 2018的一部分在Java 11(JEP 321)中正确发布。