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

问题描述 投票:0回答:1

最近我从 Apache Commons Http Client 3.x 迁移到新的 Apache 4.x http 客户端。一切都被替换,比如多线程 Http 客户端连接管理器被替换为 PoolingHttpClientManager。除了上传大文件外,一切正常。它进入一个接受路径和输入流的 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 客户端相同的配置。

我尝试了各种修改输入流的方法,并尝试实现自定义输入流。

java tomcat apache-axis apache-httpclient-4.x apache-commons-httpclient
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.