Tomcat:关闭会导致客户端中的EOF过早错误

时间:2018-11-15 13:57:19

标签: java tomcat jersey shutdown

我有一个运行在tomcat8上的servlet(使用Jersey)和一个用Java编写的客户端应用程序。要将从客户端应用程序导出的数据直接传输到Web服务器(而不是先导出所有数据然后再上传数据),我使用的是自定义InputStream实现。

一切正常,除了在这种情况下:

我正在从客户端开始数据传输,然后在数据仍在传输时关闭tomcat。日志消息显示请求已完成(我将unloadDelay设置为一个很高的值,以确保请求在关闭之前会完成),但是客户端在尝试读取响应时会抛出“ Premature EOF”异常。

我验证了流已完全传输到服务器。因此,在服务器处理InputStream之后,它将作为结果返回一个String,但是当尝试在客户端中读取结果时,服务器已经消失了。

如何才能正常关闭tomcat,这样仍在处理中的请求将完成而不会出现错误?

这是代码的一部分:

泽西资源的摘录

@POST
@Produces(MediaType.TEXT_PLAIN)
public Response handleData(InputStream data) {
    String result = service.put(data);
    log.info("handledData, result: " + result);
    return Response.status(201).entity(result).build();
}

WebRequests.java中的代码段-使用jersey调用servlet的帮助程序类

private static Builder builder(String url, String sessionId, InputStream data) {
    WebResource resource = createClient().resource(url);
    Builder builder = resource.accept(MediaType.APPLICATION_JSON_TYPE, MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_OCTET_STREAM_TYPE);
    builder.cookie(new Cookie("JSESSIONID", sessionId));
    builder.entity(data, MediaType.APPLICATION_OCTET_STREAM_TYPE);
    return builder;
}

private static Client createClient() {
    ClientConfig config = new DefaultClientConfig();
    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, false);
    Client client = Client.create(config);
    client.setChunkedEncodingSize(1024 * 100);
    return client;
}

调用代码(CommitStream是自定义输入流):

InputStream stream = new CommitStream(db, message, data, callback);
String result = WebRequests.builder("http://....", sessionId, stream).post(String.class);

Stacktrace

 java.io.IOException: Premature EOF
     at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565)
     at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:609)
     at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:696)
     at java.io.FilterInputStream.read(FilterInputStream.java:133)
     at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3444)
     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
     at java.io.InputStreamReader.read(InputStreamReader.java:184)
     at java.io.Reader.read(Reader.java:140)
     at com.sun.jersey.core.util.ReaderWriter.readFromAsString(ReaderWriter.java:171)
     at com.sun.jersey.core.util.ReaderWriter.readFromAsString(ReaderWriter.java:157)
     at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.readFromAsString(AbstractMessageReaderWriterProvider.java:114)
     at com.sun.jersey.core.impl.provider.entity.StringProvider.readFrom(StringProvider.java:73)
     at com.sun.jersey.core.impl.provider.entity.StringProvider.readFrom(StringProvider.java:58)
     at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:634) 

0 个答案:

没有答案