tomcat java.net.SocketException:从4.x迁移到Http Client 4.x后,对等端重置连接(写入失败)

wko9yo5t  于 2023-10-19  发布在  Java
关注(0)|答案(1)|浏览(151)

最近我从Apache Commons Http Client 3.x迁移到了新的Apache 4.x http客户端。所有内容都被替换,如多线程Http客户端连接管理器到PoolingHttpClientManager。除了上传大文件外,一切都正常。它进入了一个接受path和Input流的put方法,当我试图上传一个大文件时,它失败了。这是只有当我把我的程序放在云上时才能正常工作的行为,如果我把它创建为exe文件并安装它,在Eclipse环境中也能正常工作。我使用的是tomcat的webdav功能,在云中,webdav服务器被放置在代理之后。下面是上传文件时使用的putMethod的代码

HttpPut method = null;
    try
    {
      method = new HttpPut(this.encodePath(path));
      setProxy(method);
    }
    catch (MalformedURLException | URISyntaxException ex)
    {
      throw new HttpURIException();
    }

    String contentType = getGetContentType();
    if ((contentType != null) && (contentType.length() > 0))
    {
      method.setHeader("Content-Type", contentType);
    }
    InputStreamEntity ise = new InputStreamEntity(inputStream);
    ise.setChunked(true);
    ise.setContentType(contentType);
    BufferedHttpEntity bhe = new BufferedHttpEntity(ise);
    method.setEntity(bhe);
    try
    {
      HttpResponse response = this.client.execute(method);
      return (response.getStatusLine().getStatusCode() >= 200) && (response.getStatusLine().getStatusCode() < 300);
    }
    finally
    {
      method.releaseConnection();
    }
  }

以下是错误的堆栈跟踪

ERROR - FileUploadHandler     - IO Error while file upload. java.net.SocketException: Connection reset by peer (Write failed) at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:?] at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110) ~[?:?] at java.net.SocketOutputStream.write(SocketOutputStream.java:150) ~[?:?] at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:160) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:120) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.entity.BufferedHttpEntity.writeTo(BufferedHttpEntity.java:105) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123) ~[httpcore-4.4.13.jar:4.4.13] at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.13.jar:4.5.13]

在最新的客户端中,我使用以下方法创建一个新客户端

PoolingHttpClientConnectionManager conManager = new PoolingHttpClientConnectionManager();
    connectionManager.setMaxTotal(40);
    connectionManager.setDefaultMaxPerRoute(20);
    RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(CONNECTION_TIMEOUT).build();

    SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(SO_TIMEOUT).build();

    HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(HTTPMETHOD_RETRY_COUNT, false);

    HttpClientBuilder clientBuilder = HttpClients.custom().useSystemProperties().setConnectionManager(conManager).setDefaultRequestConfig(defaultRequestConfig).setDefaultSocketConfig(socketConfig).setRetryHandler(retryHandler);

      credentials = new UsernamePasswordCredentials(userName, password);
      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

      credentialsProvider.setCredentials(getAuthScope(aHttpUrl), credentials);

      clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
    boolean shouldUseProxy = isProxy(aConfig);

    String proxyHost = System.getProperty(PROPERTY_PROXY_HOST);
    if (shouldUseProxy)
    {
      String proxyPort = System.getProperty(PROPERTY_PROXY_PORT, "80");
      HttpHost proxyHosts = new HttpHost(proxyHost, Integer.parseInt(proxyPort));
      RequestConfig config = RequestConfig.copy(defaultRequestConfig).setProxy(proxyHosts).build();
      clientBuilder.setDefaultRequestConfig(config);
    }

有什么我需要添加或修改的吗?或者我应该改变代理服务器的一些超时设置?通过代码,我将超时设置为5000,并将重试计数设置为3。
使用相同的配置,它可以与旧的http客户端一起工作。
我尝试了各种修改输入流的方法,并尝试实现自定义输入流。

3pmvbmvn

3pmvbmvn1#

它的工作原理是在方法执行时修改代码。您可以传递一个上下文变量,它可以帮助您在方法执行时进行身份验证。

相关问题