httpcomponents的ssl连接结果在socket中被关闭

时间:2013-06-11 09:26:20

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

我正在尝试从网络服务器获取一些与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();

        }

1 个答案:

答案 0 :(得分:0)

基本上,答案是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块在读取流之前关闭了流。