Content-Length 分隔的消息体过早结束
Posted
技术标签:
【中文标题】Content-Length 分隔的消息体过早结束【英文标题】:Premature end of Content-Length delimited message body 【发布时间】:2020-09-14 16:35:15 【问题描述】:我调试了代码,我得到的错误是在obj.close()
语句之后。我只需要 S3 对象的最后修改日期。
AmazonS3 s3 = AmazonS3ClientBuilder
.standard()
.withCredentials(new DefaultAWSCredentialsProviderChain())
.withRegion(Regions.US_EAST_1)
.build();
S3Object obj = null;
try
obj = s3.getObject("bucketName","abc/1.txt");
obj.getObjectContent();
Date date = obj.getObjectMetadata().getLastModified();
System.out.println(date);
finally
if(obj!=null)
obj.close();
错误:
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 12; received: 0
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200)
at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103)
at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:140)
at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228)
at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174)
at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
at com.amazonaws.event.ProgressInputStream.close(ProgressInputStream.java:211)
at com.amazonaws.util.IOUtils.closeQuietly(IOUtils.java:70)
at com.amazonaws.services.s3.internal.S3AbortableInputStream.close(S3AbortableInputStream.java:185)
at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
at com.amazonaws.services.s3.model.S3ObjectInputStream.close(S3ObjectInputStream.java:136)
at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
at com.amazonaws.event.ProgressInputStream.close(ProgressInputStream.java:211)
at java.base/java.io.FilterInputStream.close(FilterInputStream.java:180)
at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
at com.amazonaws.services.s3.model.S3ObjectInputStream.close(S3ObjectInputStream.java:136)
at com.amazonaws.services.s3.model.S3Object.close(S3Object.java:225)
【问题讨论】:
这也是我日志的一部分:[main] WARN com.amazonaws.services.s3.internal.S3AbortableInputStream - 并非所有字节都从 S3ObjectInputStream 中读取,因此中止 HTTP 连接。这很可能是一个错误,并可能导致次优行为。仅通过远程 GET 请求您需要的字节,或在使用后排空输入流。 21:25:38.161 [main] 调试 org.apache.http.impl.execchain.MainClientExec - 取消请求执行 这种情况有时会发生还是总是会发生?你当时有网络连接吗? 它总是会发生,是的,网络连接在那里 文件有多大? 其实很小,大约 12 个字节 【参考方案1】:发生这种情况是因为您调用了s3.getObject()
,但没有读取它检索到的内容。 SDK 假定如果您检索到对象数据,您就会使用它。
如果您只关心对象元数据,您应该直接在AmazonS3
客户端对象上调用getObjectMetadata()
。
【讨论】:
我尝试在 AmazonS3 客户端上直接调用 getObjectMetadata,但由于无法关闭此对象,我想我得到了以下错误日志 !原因:com.amazonaws.SdkClientException:无法执行 HTTP 请求:超时等待来自池的连接!在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686) !在 com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550) !在 com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530) !在 com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5062) !在 com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5008) !在 com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1338) !在 com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1312) !在 com.amazonaws.services.s3.AmazonS3Client.doesObjectExist(AmazonS3Client.java:1393) 重启服务器后问题已经消失。直接调用 getObjecMetadata("bucketName, "key") 似乎至少目前有效以上是关于Content-Length 分隔的消息体过早结束的主要内容,如果未能解决你的问题,请参考以下文章
HTTP/1.1 客户端如何知道在存在“Connection: keep-alive”头字段但没有“Content-Length”的情况下消息在哪里结束?