我在web应用程序中使用Jersey 2.13异步检索数据。在某些情况下,请求需要一段时间(即在执行复杂报告时)才能返回到客户端。
当客户端不等待异步响应(离开页面、关闭浏览器等)时,将引发ClientAbortException。这种行为与预期的一样,但它正在用堆栈跟踪淹没我的日志文件,因为在响应返回之前被取消的每个异步请求都会打印一个堆栈跟踪。
堆栈跟踪如下所示:
Oct 15, 2014 2:25:23 PM org.glassfish.jersey.server.ServerRuntime$Responder writeResponse
SEVERE: An I/O error has occurred while writing a response message entity to the container output stream.
org.glassfish.jersey.server.internal.process.MappableException: ClientAbortException: java.io.IOException
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:91)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1154)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:621)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:377)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:367)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:274)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: ClientAbortException: java.io.IOException
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:438)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:426)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
at org.glassfish.jersey.servlet.internal.ResponseWriter$NonCloseableOutputStreamWrapper.write(ResponseWriter.java:298)
at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:229)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:299)
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:1862)
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.close(UTF8JsonGenerator.java:1087)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.writeTo(ProviderBase.java:637)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85)
... 38 more
Caused by: java.io.IOException
at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:205)
at org.apache.coyote.http11.InternalAprOutputBuffer.access$100(InternalAprOutputBuffer.java:37)
at org.apache.coyote.http11.InternalAprOutputBuffer$SocketOutputBuffer.doWrite(InternalAprOutputBuffer.java:235)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:117)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:517)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408)
... 55 more
我还使用Jersey ExceptionMapper来映射几个异常,但这两种方法都不适用于
org.glassfish.jersey.server.internal.process.MappableException
也不是为了
org.apache.catalina.connector.ClientAbortException
有没有办法捕获此异常并阻止打印整个堆栈跟踪?
编辑:
仍然在寻找答案。。。
感谢@Chip,它还可以将代码直接放入WS。
@Path("/myWS")
public class MyWS {
private final static Logger ORG_GLASSFISH_JERSEY_LOGGER = Logger.getLogger("org.glassfish.jersey");
static {
ORG_GLASSFISH_JERSEY_LOGGER.setLevel(Level.OFF);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/version")
public String version() {
return "1.0.25";
}
}
我也遇到过这个问题,最终找到了一个“解决”这个问题的指南。
https://tutorial-academy.com/jersey-workaround-clientabortexception-ioexception/
有两个选项,第一个选项是目前公认的答案。另一种首选方式是添加WriterInterceptor以删除ClientAbortExcema。我个人的改变是警告记录这种情况。
如果无法访问URL,我将在此处添加我的实现。别忘了在你的球衣环境中注册它。
import org.apache.catalina.connector.ClientAbortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Priority;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
@Provider
@Priority(1)
public class ClientAbortExceptionWriterInterceptor implements WriterInterceptor {
private static final Logger logger = LoggerFactory.getLogger(ClientAbortExceptionWriterInterceptor.class);
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException {
try {
context.proceed();
} catch (Throwable t) {
for (Throwable cause = t; cause != null; cause = cause.getCause()) {
if (cause instanceof ClientAbortException) {
logger.warn("Client aborted request.", cause);
return;
}
}
throw t;
}
}
}
我通过添加一个低优先级WriterInterceptor
来解决这个问题,它可以检测并忽略在编写响应时抛出的异常。如果您在Tomcat上运行并且不介意对Tomcat类的依赖,您可以使用org.apache.catalina.connector.ClientAbortExc0019
而不是调用setOutputStream
,这将消除对两个嵌套类的需求(以及对<-Plhd--1/>ProxyOutputStream
,这也可以很容易地避免使用自定义的OutputStream
子类)。
import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.Priority;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import org.apache.commons.io.output.ProxyOutputStream;
/**
* Ignore exceptions when writing a response, which almost always means the
* client disconnected before reading the full response.
*/
@Provider
@Priority(1)
public class ClientAbortExceptionWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException {
context.setOutputStream(new ClientAbortExceptionOutputStream(context.getOutputStream()));
try {
context.proceed();
} catch (Throwable t) {
for (Throwable cause = t; cause != null; cause = cause.getCause()) {
if (cause instanceof ClientAbortException) {
return;
}
}
throw t;
}
}
private static class ClientAbortExceptionOutputStream extends ProxyOutputStream {
public ClientAbortExceptionOutputStream(OutputStream out) {
super(out);
}
@Override
protected void handleIOException(IOException e) throws IOException {
throw new ClientAbortException(e);
}
}
@SuppressWarnings("serial")
private static class ClientAbortException extends IOException {
public ClientAbortException(IOException e) {
super(e);
}
}
}
我有两个应用程序:App1和App2 在App1中指定的权限如下所示 java.lang.SecurityException:权限拒绝:从PID=5550,UID=10919读取com.commonname.providers.app1 uri内容://com.commonname.providers.app1.read_login_token或ranturiPermission()(位于Andr
有没有办法在使用 jongo 查询 MongoDB 时添加 ?我发现这样的错误 - '排序超出了 104857600 字节的内存限制,但没有选择加入外部排序。正在中止操作。传递 allowDiskUse:true 可以选择加入,可以通过以下方式阻止,您的聚合看起来像 但据我所知,Jongo 中的类仅将管道应用于自身,然后您可以使用 方法执行。 是否有任何方法可以将该参数传递给mongo而不从Jon
问题内容: 我在Web应用程序中使用Jersey 2.13检索数据异步。在某些情况下,请求需要一段时间(即执行复杂报告时,即EE)才能将响应返回给客户端。 当客户端不等待异步响应(离开页面,关闭浏览器等)时,将抛出ClientAbortException。此行为是预期的,但它使堆栈跟踪淹没了我的日志文件,因为在响应返回之前被取消的每个单个异步请求都会打印堆栈跟踪。 堆栈跟踪如下所示: 我也正在使用
我正在利用Java Mail API开发一个发送邮件的应用程序。如果我使用雅虎或gmail托管的邮件服务器,我可以成功地发送邮件。然而,当我尝试使用自己的邮件服务器时,我无法发送邮件,导致失败的可能原因是什么?当我在我的设备上执行我的应用程序时,它会显示“电子邮件未发送”,因此不会发生异常。我想问一下,如何更改程序,以便将我的应用程序成功连接到smtp服务器,或者如何获得更多信息以显示,从而了解连
我刚开始使用线程,一调用wait方法就会得到一个IllegalMonitorStateException,有人能帮我吗