【问题标题】:httpcomponents's ssl connection results in socket is closedhttpcomponents的ssl连接导致socket关闭
【发布时间】:2013-06-11 09:26:20
【问题描述】:

我正在尝试从网络服务器获取一些与 http 配合良好的数据。

但是当我尝试使用 https(ssl 连接)时,我得到了如下异常。

我得到了正确的 http 状态码 200 和响应内容长度 2230。

        java.net.SocketException: Socket is closed
            at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1483)
            at sun.security.ssl.AppInputStream.read(AppInputStream.java:92)
            at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
            at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
            at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:183)
            at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:144)
            at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:121)

我的代码如下所示,带有 apache httpcomponents httpclient(4.2.5) 库。

        try {
            HttpPost httppost = new HttpPost(uri);
            HttpHost targetHost = new HttpHost(HOST_NAME, HOST_PORT, PROTOCOL);

            InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(request), -1);
            String contentType = TSPConstants.CONST_TSA_CONTENT_TYPE_TSREQUEST;
            reqEntity.setContentType(contentType);
            reqEntity.setChunked(true);
            // It may be more appropriate to use FileEntity class in this particular
            // instance but we are using a more generic InputStreamEntity to demonstrate
            // the capability to stream out data from any arbitrary source
            //
            // FileEntity entity = new FileEntity(file, "binary/octet-stream");

            httppost.setEntity(reqEntity);

            //Authentication
            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                    new UsernamePasswordCredentials(id, password));
            // Create AuthCache instance
            AuthCache authCache = new BasicAuthCache();
            // Generate BASIC scheme object and add it to the local
            // auth cache
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(targetHost, basicAuth);

            // Add AuthCache to the execution context
            BasicHttpContext httpContext = new BasicHttpContext();
            httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
            httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

            //SSL
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

                public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

              Scheme sch = new Scheme("https", HOST_PORT, ssf);

              httpclient.getConnectionManager().getSchemeRegistry().register(sch);
            System.out.println("executing request " + httppost.getRequestLine());
            httpclient.execute(httppost, httpContext);
                    HttpResponse response = send(request);

            HttpEntity resEntity = response.getEntity();
            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (resEntity != null) {
                System.out.println("Response content length: " + resEntity.getContentLength());
                System.out.println("Chunked?: " + resEntity.isChunked());
            }

            EntityUtils.consume(resEntity);
                resEntity.getContent()


        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpclient.getConnectionManager().shutdown();

        }

【问题讨论】:

  • 我知道这已经有一段时间了,但你有没有得到这个答案...?
  • 在读取实体之前调用 response.close() 导致出现此错误。

标签: ssl apache-httpclient-4.x apache-httpcomponents


【解决方案1】:

基本上答案在comment 中给出了@Avner。

问题(对我来说)是,在读取实体之前响应已关闭。

我做了这样的事情,这是错误的

HttpEntity entity = null;
try (CloseableHttpResponse response = client.execute(request)) {
     entity = response.getEntity();
}
read(entity);

以下有效

try (CloseableHttpResponse response = client.execute(request)) {
     HttpEntity  entity = response.getEntity();
     read(entity);
}

也许不是那么明显部分:第一个示例中的 try-with-resources 块在读取流之前关闭了流。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 2013-05-23
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 2020-09-22
    相关资源
    最近更新 更多