httpcomponents的ssl连接导致套接字已关闭

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

我正在尝试从Web服务器上获取一些与http兼容的数据。

但是当我尝试使用https(ssl connection)时,出现如下异常。

我得到了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();

        }
ssl apache-httpclient-4.x apache-httpcomponents
1个回答
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);
}

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

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