java.net.http.HttpClient使用示例解析
java自帶HttpClient使用
在使用java自帶的HttpClient時, 發(fā)現(xiàn)一個現(xiàn)象,即有些以前常用http的header, 是不能夠set到請求里進行傳遞的,在jdk.internal.net.http.common.Utils類中,可以看到
private static Set<String> getDisallowedHeaders() { Set<String> headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); headers.addAll(Set.of("connection", "content-length", "expect", "host", "upgrade")); String v = getNetProperty("jdk.httpclient.allowRestrictedHeaders"); if (v != null) { // any headers found are removed from set. String[] tokens = v.trim().split(","); for (String token : tokens) { headers.remove(token); } return Collections.unmodifiableSet(headers); } else { return Collections.unmodifiableSet(headers); } }
connection, content-length, expect, host, upgrade這幾個, 屬于禁止設(shè)置的。
校驗
因為在jdk.internal.net.http.HttpRequestBuilderImpl中, 會進行嚴(yán)格的校驗
private void checkNameAndValue(String name, String value) { requireNonNull(name, "name"); requireNonNull(value, "value"); if (!isValidName(name)) { throw newIAE("invalid header name: \"%s\"", name); } if (!Utils.ALLOWED_HEADERS.test(name, null)) { throw newIAE("restricted header name: \"%s\"", name); } if (!isValidValue(value)) { throw newIAE("invalid header value: \"%s\"", value); } }
控制連接復(fù)用
它自己控制連接的復(fù)用,所以設(shè)置不了connection這個header.從jdk.internal.net.http.ConnectionPool中可以看出一些參數(shù)
static final long KEEP_ALIVE = Utils.getIntegerNetProperty( "jdk.httpclient.keepalive.timeout", 1200); // seconds static final long MAX_POOL_SIZE = Utils.getIntegerNetProperty( "jdk.httpclient.connectionPoolSize", 0); // unbounded
jdk.internal.net.http.HttpConnection
從jdk.internal.net.http.HttpConnection中可以看到連接如何放入池中
/** * Forces a call to the native implementation of the * connection's channel to verify that this channel is still * open. * <p> * This method should only be called just after an HTTP/1.1 * connection is retrieved from the HTTP/1.1 connection pool. * It is used to trigger an early detection of the channel state, * before handling the connection over to the HTTP stack. * It helps minimizing race conditions where the selector manager * thread hasn't woken up - or hasn't raised the event, before * the connection was retrieved from the pool. It helps reduce * the occurrence of "HTTP/1.1 parser received no bytes" * exception, when the server closes the connection while * it's being taken out of the pool. * <p> * This method attempts to read one byte from the underlying * channel. Because the connection was in the pool - there * should be nothing to read. * <p> * If {@code read} manages to read a byte off the connection, this is a * protocol error: the method closes the connection and returns false. * If {@code read} returns EOF, the method closes the connection and * returns false. * If {@code read} throws an exception, the method returns false. * Otherwise, {@code read} returns 0, the channel appears to be * still open, and the method returns true. * @return true if the channel appears to be still open. */ final boolean checkOpen() { if (isOpen()) { try { // channel is non blocking int read = channel().read(ByteBuffer.allocate(1)); if (read == 0) return true; close(); } catch (IOException x) { debug.log("Pooled connection is no longer operational: %s", x.toString()); return false; } } return false; }
void closeOrReturnToCache(HttpHeaders hdrs) { if (hdrs == null) { // the connection was closed by server, eof Log.logTrace("Cannot return connection to pool: closing {0}", this); close(); return; } HttpClientImpl client = client(); if (client == null) { Log.logTrace("Client released: closing {0}", this); close(); return; } ConnectionPool pool = client.connectionPool(); boolean keepAlive = hdrs.firstValue("Connection") .map((s) -> !s.equalsIgnoreCase("close")) .orElse(true); if (keepAlive && checkOpen()) { Log.logTrace("Returning connection to the pool: {0}", this); pool.returnToPool(this); } else { Log.logTrace("Closing connection (keepAlive={0}, isOpen={1}): {2}", keepAlive, isOpen(), this); close(); } }
以上就是java.net.http.HttpClient使用示例解析的詳細內(nèi)容,更多關(guān)于java.net.http.HttpClient的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java普通項目讀取不到resources目錄下資源文件的解決辦法
這篇文章主要給大家介紹了關(guān)于java普通項目讀取不到resources目錄下資源文件的解決辦法,Web項目中應(yīng)該經(jīng)常有這樣的需求,在maven項目的resources目錄下放一些文件,比如一些配置文件,資源文件等,需要的朋友可以參考下2023-09-09在 Spring Boot 項目中實現(xiàn)文件下載功能
這篇文章主要介紹了在 Spring Boot 項目中實現(xiàn)文件下載功能,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09Python中scrapy框架的ltem和scrapy.Request詳解
這篇文章主要介紹了Python中scrapy框架的ltem和scrapy.Request詳解,Item是保存爬取數(shù)據(jù)的容器,它的使用方法和字典類似,不過,相比字典,Item提供了額外的保護機制,可以避免拼寫錯誤或者定義字段錯誤,需要的朋友可以參考下2023-09-09