gpt4 book ai didi

java - 在 java 11 上的 SSL 通信期间发生 SocketException 时,如何使用 DefaultHttpRequestRetryHandler(HTTPClient) 重试?

转载 作者:行者123 更新时间:2023-11-30 10:03:35 25 4
gpt4 key购买 nike

我应该如何实现它才能使用 httpclient 重试 SSL 通信在 java11 上?

如下所示覆盖DefaultHttpRequestRetryHandler是否更好?
有更好的方法吗?

  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
IOException cause = exception;
if (exception instanceof SSLException) {
if (exception.getCause() != null && exception.getCause() instanceof IOException) {
cause = (IOException) exception.getCause();
}
}
return super.retryRequest(cause, executionCount, context);
}
}

在 Java 11 中,不会重试 SocketException,因为 SocketException 是用 SSLException 包装的。

我阅读了以下内容。

使用java11时,随机出现以下错误,概率小于0.01%。

javax.net.ssl.SSLException: Connection reset
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:839)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
... 81 common frames omitted
Suppressed: java.net.SocketException: Broken pipe (Write failed)
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:352)
... 106 common frames omitted
Caused by: java.net.SocketException: Connection reset
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:448)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68)
at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1104)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:823)
... 102 common frames omitted

最佳答案

我创建了 HttpRequestRetryHandler 类。

  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
IOException cause = exception;
if (exception instanceof SSLException) {
if (exception.getCause() != null && exception.getCause() instanceof IOException) {
cause = (IOException) exception.getCause();
}
}
return super.retryRequest(cause, executionCount, context);
}
}

并将其设置为 HttpClientBuilder。

CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(new HttpRequestRetryHandler())
.build();

结论

  • SSL 通信质量与使用 java8 时相同。
  • 服务器或网络底层问题依然存在,但java11的影响已经解决。

关于java - 在 java 11 上的 SSL 通信期间发生 SocketException 时,如何使用 DefaultHttpRequestRetryHandler(HTTPClient) 重试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56306216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com