Ich weiß nicht, was ich getan habe, also schreibe ich auf, was ich geändert habe.
** Unterstützt wichtige Änderungen an der Benutzeroberfläche von Java Apache HttpClient 4.3 (@mychaelstyle) ** https://qiita.com/mychaelstyle/items/e02b3011d1e71bfa26c5 ** Apache httpclient CloseableHttpClient an HTTPS-Site-Anfrage mit BASIC-Authentifizierung (@sh_kawakami) ** https://qiita.com/sh_kawakami/items/bf6d1397851cccd134b2 ** Es scheint, dass sich die Oberfläche von httpclient von 4.3 (@sakito) erheblich geändert hat ** https://qiita.com/sakito/items/6366015dbbc4a88d56fc What does setDefaultMaxPerRoute and setMaxTotal mean in HttpClient? Antwortspalte von https://stackoverflow.com/questions/30689995/what-does-setdefaultmaxperroute-and-setmaxtotal-mean-in-httpclient
JDK 1.8.162 httpclient 4.5.4
pom.xml
pom.xml
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.4</version>
</dependency>
Ich habe mich umgesehen, als hätte mir die veraltete Liste noch nie geholfen
―― 3.x-Serie https://hc.apache.org/httpclient-3.x/apidocs/deprecated-list.html ―― 4.x Serie http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/deprecated-list.html
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html
Da es sich um eine Richtlinie beim Erhöhen von 3.x auf 4.0 handelt, kann es sich bei Erreichen von 4.5 erneut ändern. http://debuguide.blogspot.jp/2013/01/quick-guide-for-migration-of-commons.html
―― 3.x-Serie https://hc.apache.org/httpclient-3.x/apidocs/constant-values.html ―― 4.x Serie http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/constant-values.html
before.java
HttpClient client = new HttpClient();
Verwenden wir Builder! Es scheint, dass. Wenn Sie an nichts denken müssen, siehe unten.
after.java
HttpClient client = HttpClients.createDefault();
Dies ist jedoch möglicherweise nicht sehr praktisch, da Sie die Verbindungseinstellungen zum Zeitpunkt der Generierung übergeben müssen.
GetMethod→HttpGet PostMethod→HttpPost Übergeordnete Klasse HttpMethod → HttpRequestBase Ändern
Früher war es so
before.java
PostMethod post = new PostMethod(url);
post.setRequestEntity(Setze etwas);
int responseCode = client.executeMethod(post);
if (responseCode == 200) {
Reader reader = new InputStreamReader(
httpMethod.getResponseBodyAsStream(), httpMethod.getResponseCharSet());
//Nachbearbeitung
} else {
//Fehlerbehandlung
}
Es hat sich sehr verändert und sieht so aus. Aber jetzt, da es klar ist, ist es vielleicht einfacher zu verstehen.
after.java
HttpPost post = new HttpPost(url);
//Legen Sie diejenige fest, die dem Anforderungshauptteil entspricht
post.setEntity(Setze etwas);
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
int responseCode = statusLine.getStatusCode();
if (responseCode == HttpStatus.SC_OK) {
Reader reader = new InputStreamReader(
response.getEntity().getContent(), Charset.forName("UTF-8"));
//Nachbearbeitung
} else {
//Fehlerbehandlung
}
Ich habe es so gemacht.
before.java
Credentials credentials = new UsernamePasswordCredentials(this.username, this.password);
AuthScope scope = new AuthScope(host, port, this.realm);
client.getState().setCredentials(scope, credentials);
Es scheint, dass Sie CredentialsProvider verwenden sollten. (Danke an @sh_kawakami!)
after.java
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(baseUrl.getHost(),baseUrl.getPort()),
new UsernamePasswordCredentials(username, password));
//Ich werde es beim Erstellen einer Instanz festlegen
HttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build();
Es scheint, dass die Entitätsklasse jetzt BasicNameValuePair ist. Es scheint, dass es nur durch "=" geteilt wird, also bete ich, dass sich das Verhalten nicht wie zuvor ändert. Aber der Setter ist weg! !! !! Aus meiner Sicht kann es anscheinend nur mit dem Konstruktor festgelegt werden. Wenn Sie Setter weiterhin verwenden möchten, müssen Sie NameValuePair erben und eine eigene Klasse erstellen.
Lassen Sie es uns selbst hinzufügen
//Host-Header
httpMethod.addHeader("Host", uri.getHost());
Tritt auf, wenn sich die Größe der Antwort vom Text unterscheidet, wenn ein Content-Length-Header vorhanden ist. Dies geschieht nicht ohne den Content-Length-Header (obwohl es sich wie eine RFC-Verletzung anfühlt). Zum Beispiel tritt es auf, wenn die Antwort so ist. Nun, heute denke ich, dass die Inhaltslänge automatisch vom Server ohne Erlaubnis berechnet und zurückgegeben wird, daher denke ich, dass dies unwahrscheinlich ist, aber aus verschiedenen Gründen vertraue ich dem Antwortheader nicht.
HTTP/1.1 200 OK
Content-Type: text/html; charset=Shift_JIS
Content-Length: 3000
<html>
<head><title>Hoge</title>
</head>
<body>test
</body>
</html>
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 3000; received: 124
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:148)
Die Ursache ist hier
java:org.apache.http.impl.io.ContentLengthInputStream.java
/**
* Does standard {@link InputStream#read(byte[], int, int)} behavior, but
* also notifies the watcher when the contents have been consumed.
*
* @param b The byte array to fill.
* @param off Start filling at this position.
* @param len The number of bytes to attempt to read.
* @return The number of bytes read, or -1 if the end of content has been
* reached.
*
* @throws java.io.IOException Should an error occur on the wrapped stream.
*/
@Override
public int read (final byte[] b, final int off, final int len) throws java.io.IOException {
if (closed) {
throw new IOException("Attempted read from closed stream.");
}
if (pos >= contentLength) {
return -1;
}
int chunk = len;
if (pos + len > contentLength) {
chunk = (int) (contentLength - pos);
}
final int count = this.in.read(b, off, chunk);
if (count == -1 && pos < contentLength) {
throw new ConnectionClosedException(
"Premature end of Content-Length delimited message body (expected: "
+ contentLength + "; received: " + pos);
}
if (count > 0) {
pos += count;
}
return count;
}
Ich habe bisher keine Lösung gefunden.
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <hostname> doesn't match any of the subject alternative names:
Es scheint, dass der Hostname standardmäßig überprüft wird. Der relevante Teil ist hier
java:org.apache.http.conn.ssl.SSLConnectionSocketFactory.java#verifyHostname
if (!this.hostnameVerifier.verify(hostname, session)) {
final Certificate[] certs = session.getPeerCertificates();
final X509Certificate x509 = (X509Certificate) certs[0];
final List<SubjectName> subjectAlts = DefaultHostnameVerifier.getSubjectAltNames(x509);
throw new SSLPeerUnverifiedException("Certificate for <" + hostname + "> doesn't match any " +
"of the subject alternative names: " + subjectAlts);
}
Es scheint, dass Sie eine Instanz der NoopHostnameVerifier-Klasse verwenden können, da verify nur true zurückgeben muss. Deaktivieren Sie die Überprüfung des SSL-Zertifikats und des Hostnamens in Apache HttpComponents / Client Chapter 2. Connection management 2.7.4. Hostname verification In meinem Fall setze ich SSLContext oder SSLConnectionSocketFactory nicht direkt in httpclient, sondern implementiere es, indem ich es in ConnectionManager einstelle. An diesem Punkt. Es sieht also wie folgt aus.
public static PoolingHttpClientConnectionManager createConnectionManager() {
SSLContext sslContext = null;
try {
sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy(){
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}
).build();
} catch (Exception e) {
e.printStackTrace();
}
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry =
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslsf)
.build();
return new PoolingHttpClientConnectionManager(registry);
}
Der DefaultHttpRequestRetryHandler von Apache HttpClient versucht es nicht erneut mit ConnectTimeoutException http://kntmr.hatenablog.com/entry/2016/12/09/150615 Use of non-ascii credentials not working in httpclient 4.3.x https://stackoverflow.com/questions/27955067/use-of-non-ascii-credentials-not-working-in-httpclient-4-3-x
Recommended Posts