5

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

        }
4

1 回答 1

0

基本上答案在评论中给了@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块在读取流之前关闭了流。

于 2020-01-24T14:42:05.437 回答