Боюсь, что это невозможно в HTTP-клиенте Java 11.
Наиболее релевантный внутренний класс JDK: Http2Connection.java .В нем перечислены три случая «создания», которые мы ожидаем для HTTP / 2-соединений:
- обновленное HTTP / 1.1 обычное TCP-соединение
- предшествующее знание непосредственно созданного простого TCP-соединения
- непосредственно созданное соединение HTTP / 2 SSL, которое использует ALPN.
Нас интересует случай 2. Есть код для этого:
/**
* Cases 2) 3)
*
* request is request to be sent.
*/
private Http2Connection(HttpRequestImpl request,
Http2ClientImpl h2client,
HttpConnection connection)
throws IOException
{
...
}
Увы, этот конструкторфактически используется только из метода для безопасных соединений:
// Requires TLS handshake. So, is really async
static CompletableFuture<Http2Connection> createAsync(HttpRequestImpl request,
Http2ClientImpl h2client,
Exchange<?> exchange) {
assert request.secure();
AbstractAsyncSSLConnection connection = (AbstractAsyncSSLConnection)
...
return connection.connectAsync(exchange)
.thenCompose(unused -> connection.finishConnect())
.thenCompose(unused -> checkSSLConfig(connection))
.thenCompose(notused-> {
CompletableFuture<Http2Connection> cf = new MinimalFuture<>();
try {
Http2Connection hc = new Http2Connection(request, h2client, connection);
cf.complete(hc);
} catch (IOException e) {
cf.completeExceptionally(e);
}
return cf; } );
Кажется, что конструкторы не-TLS вызываются только при обновлении соединения HTTP 1.1.
Я просмотрел многиеиз других классов тоже.Я не вижу ничего, что указывало бы на то, что можно установить согласование HTTP / 2-соединений в открытом тексте без обновления HTTP 1.1 в клиенте JDK 11.
То, что я нахожу, очень соответствует описанию API в javadocs для HttpClient.Builder , в котором говорится только о выборе HTTP / 2 в качестве версии:
Если установлено значение HTTP / 2, то каждый запрос будет пытаться обновиться до HTTP / 2.Если обновление выполнено успешно, то ответ на этот запрос будет использовать HTTP / 2, а все последующие запросы и ответы на тот же сервер происхождения будут использовать HTTP / 2.Если обновление завершится неудачно, ответ будет обработан с использованием HTTP / 1.1
В повторном использовании соединения HTTP / 2 происходит много интересного.Например, при одновременном обновлении одновременных запросов остается только один для последующего использования в «кэше» HTTP / 2-соединения.Кэшированное соединение истечет, когда число потоков достигнет максимума, который составляет ~ 2 ^ 31-1, так что дальнейшие запросы не превысят его, но существующие потоки останутся открытыми.Это много потоков.Я думаю, что если ваш вариант использования похож на мой - клиент веб-службы в приложениях с очень длительным запуском - тогда стоимость обновления практически только для первого запроса незначительна.Я все еще хотел бы устранить это, главным образом для простоты, но я начинаю думать, что оно того не стоит.
Как тот, кто спрашивает, я хотел бы придерживаться клиента JDK.Я просто упомяну, что бета-версия Apache HttpClient 5 поддерживает форсирование HTTP / 2 (HttpVersionPolicy.FORCE_HTTP_2).Я не могу давать дальнейшие рекомендации по этому поводу, потому что бета-версия не имеет много документации, и комментарии гораздо более редки, чем реализация JDK.Но если я попробую это сделать и добьюсь успеха, я обновлю свой ответ.