java - Java 11 上的 SocketTimeout,但 Java 8 上没有

标签 java java-8 okhttp java-11

当我的 Java 程序使用 Java 8 和 Java 11 运行时,我有一个非常奇怪的行为差异。

我正在使用 MSGraph API (1.7.0) 对 Onedrive API 进行多次调用。为了进行这些调用,我使用 4 个并行线程来同步硬盘上的大量文件(大约 1000 个)。

当我使用 Java 8 执行程序时,我没有遇到任何异常。当我使用 java 11 执行它时,我在大约 60% 的调用中得到了 Socket Timeout Exception。

配置IGraphServiceClient ,我使用的是默认配置。就我而言,在这种情况下,HTTP Provider 是 OKHttp3。

有没有人经历过这样的事情?

[UPDATE-1]

这些是我测试过的环境:

  • Oracle 的 JDK 1.8.0_192 --> 完美。大约 400 次调用中没有错误
  • Openjdk 11.0.7 和 Oracle 的 jdk 11.0.3 --> 大量 Sokcet 超时异常

  • 因此,您有堆栈跟踪:
    com.microsoft.graph.core.ClientException: Error during http request
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:422) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:204) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:184) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.BaseStreamRequest.send(BaseStreamRequest.java:85) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.requests.extensions.DriveItemStreamRequest.get(DriveItemStreamRequest.java:55) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveServiceClient.download(OnedriveServiceClient.java:236) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveFile.download(OnedriveFile.java:42) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.model.wrapper.RemoteFile.download(RemoteFile.java:20) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.downloadIntoTemp(LocalFileDownloadSyncTask.java:71) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.execute(LocalFileDownloadSyncTask.java:54) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.Syncer.lambda$taskRunner$1(Syncer.java:66) ~[easybox-0.1-SNAPSHOT.jar:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
    Caused by: java.net.SocketTimeoutException: timeout
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.java:656) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.java:664) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.java:153) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:131) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.TelemetryHandler.intercept(TelemetryHandler.java:35) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RedirectHandler.intercept(RedirectHandler.java:123) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RetryHandler.intercept(RetryHandler.java:140) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.AuthenticationHandler.intercept(AuthenticationHandler.java:31) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.RealCall.execute(RealCall.java:92) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:356) ~[easybox-0.1-SNAPSHOT.jar:?]
        ... 15 more
    

    和第二个堆栈跟踪
    Caused by: java.net.SocketTimeoutException: timeout
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.java:656) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.java:664) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream$FramingSource.read(Http2Stream.java:398) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Codec$StreamFinishingSource.read(Http2Codec.java:205) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okio.RealBufferedSource$1.read(RealBufferedSource.java:439) ~[easybox-0.1-SNAPSHOT.jar:?]
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:252) ~[?:?]
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:292) ~[?:?]
        at java.io.BufferedInputStream.read(BufferedInputStream.java:351) ~[?:?]
        at java.io.FilterInputStream.read(FilterInputStream.java:107) ~[?:?]
        at easybox.provider.onedrive.OnedriveServiceClient.download(OnedriveServiceClient.java:239) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveFile.download(OnedriveFile.java:42) ~[easybox-0.1-SNAPSHOT.jar:?]
        ... 9 more
    

    [更新 2]

    在将 okhttp 依赖项覆盖到版本 3.14.9 和 4.7.2(可用的最新版本)之后,一切都还是一样,尽管发生了一些变化。除了通常的超时异常:
    com.microsoft.graph.core.ClientException: Error during http request
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:422) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:204) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:184) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.BaseStreamRequest.send(BaseStreamRequest.java:85) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.requests.extensions.DriveItemStreamRequest.get(DriveItemStreamRequest.java:55) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveServiceClient.download(OnedriveServiceClient.java:236) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveFile.download(OnedriveFile.java:42) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.model.wrapper.RemoteFile.download(RemoteFile.java:20) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.downloadIntoTemp(LocalFileDownloadSyncTask.java:71) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.execute(LocalFileDownloadSyncTask.java:54) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.Syncer.lambda$taskRunner$1(Syncer.java:66) ~[easybox-0.1-SNAPSHOT.jar:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
    Caused by: java.net.SocketTimeoutException: timeout
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.kt:677) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.kt:686) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:143) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:96) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:96) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.TelemetryHandler.intercept(TelemetryHandler.java:35) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RedirectHandler.intercept(RedirectHandler.java:123) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RetryHandler.intercept(RetryHandler.java:140) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.AuthenticationHandler.intercept(AuthenticationHandler.java:31) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:356) ~[easybox-0.1-SNAPSHOT.jar:?]
        ... 15 more
    

    不时出现一个新的:
    com.microsoft.graph.core.ClientException: Error during http request
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:422) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:204) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:184) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.BaseStreamRequest.send(BaseStreamRequest.java:85) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.requests.extensions.DriveItemStreamRequest.get(DriveItemStreamRequest.java:55) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveServiceClient.download(OnedriveServiceClient.java:236) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.provider.onedrive.OnedriveFile.download(OnedriveFile.java:42) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.model.wrapper.RemoteFile.download(RemoteFile.java:20) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.downloadIntoTemp(LocalFileDownloadSyncTask.java:71) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.task.LocalFileDownloadSyncTask.execute(LocalFileDownloadSyncTask.java:54) ~[easybox-0.1-SNAPSHOT.jar:?]
        at easybox.syncing.Syncer.lambda$taskRunner$1(Syncer.java:66) ~[easybox-0.1-SNAPSHOT.jar:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
    Caused by: okhttp3.internal.http2.StreamResetException: stream was reset: CANCEL
        at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:148) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:96) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:96) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.TelemetryHandler.intercept(TelemetryHandler.java:35) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RedirectHandler.intercept(RedirectHandler.java:123) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.RetryHandler.intercept(RetryHandler.java:140) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.httpcore.AuthenticationHandler.intercept(AuthenticationHandler.java:31) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197) ~[easybox-0.1-SNAPSHOT.jar:?]
        at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148) ~[easybox-0.1-SNAPSHOT.jar:?]
        at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:356) ~[easybox-0.1-SNAPSHOT.jar:?]
        ... 15 more
    

    最佳答案

    JDK9(或 JDK8 252+)上的 OkHttp,默认会协商 HTTP/2。很有可能与这种变化有关。
    尝试构建一个没有 HTTP/2 的客户端,看看你是否仍然遇到这个问题。

      val client = OkHttpClient.Builder()
          .protocols(listOf(Protocol.HTTP_1_1))
          .build()
    
    如果它修复了问题,则可能是服务器与 HTTP/2 不兼容,或者与连接重用有关,例如单个连接上的请求过多。
    kekolab 20201030 更新。
    微软通过将协议(protocol)版本限制为 1.1 来解决此问题,这与上面的 OP Yuri 所建议的完全一样。好东西,代码中引用了这个线程:https://github.com/microsoftgraph/msgraph-sdk-java/pull/473/files#

    关于java - Java 11 上的 SocketTimeout,但 Java 8 上没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62031298/

    相关文章:

    java - 使用流收集器从 java 对象获取键值

    java - 使用 jelastic 托管 Java Web 服务

    java - Spring(@SpyBean)与 Mockito(@Spy)

    java - @FunctionalInterfaces 可以有默认方法吗?

    android - 如何强制 Android 11 上的 OkHttp 使用 TLS 1.3 发送 ssl 客户端证书身份验证

    java - OKhttp h2c协议(protocol)比HTTP1.1协议(protocol)慢

    java - 如何将位图从 Android 流式传输到 Google App Engine Servlet?

    spring - 将 Java 8 代码移植到 Java 7

    java - 使用 Spark 和 Java8 从 Dataframe 获取多列的不同值计数

    junit - 如何使用 MockWebServer 验证 POST 正文的内容?