"Response is committed, can't handle exception" 两次发送相同的 Rest API 请求时出错

"Response is committed, can't handle exception" Error When sending the same Rest API request twice

我正在使用 teiid 虚拟过程创建一个 Rest API 并公开我的数据。我已经使用缓存提示启用了结果集缓存。当我两次发送相同的 API 请求时,我在第二次尝试中没有收到任何数据,并且 teiid 控制台记录了以下异常。但是,当缓存被禁用时,或者如果我在等待缓存失效(在 ttl 时间之后)后发送第二个请求,请求将被正确执行并且我得到相关的响应。我所做的另一个重要观察是,当响应大小被限制为小于某个大小时(例如,使用 LIMIT 子句将响应大小限制为 10 条记录),请求将在启用缓存的情况下得到正确处理。只有当我在特定大小(在我的例子中是 15)之后增加记录大小时才会发生这种情况。

我能否知道这背后的原因以及任何修复或解决方法,以便我可以继续使用结果集缓存而不会出现此问题。

 05:04:52,909 ERROR [io.undertow.request] (default task-20) UT005023: Exception handling request to /TestView_1/report/get_data: org.jboss.resteasy.spi.UnhandledException: RESTEASY003770: Response is committed, can't handle exception
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:167)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:471)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:415)
    at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:240)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:225)
    at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:62)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
    at io.undertow.servlet.handlers.ServletInitialHandler.access[=12=]0(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:174)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
    at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:793)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
 Caused by: java.io.IOException: already removed
    at org.teiid.common.buffer.FileStore.checkRemoved(FileStore.java:162)
    at org.teiid.common.buffer.FileStore.read(FileStore.java:156)
    at org.teiid.common.buffer.FileStore.nextBuffer(FileStore.java:223)
    at org.teiid.common.buffer.ExtensibleBufferedInputStream.ensureBytes(ExtensibleBufferedInputStream.java:42)
    at org.teiid.common.buffer.ExtensibleBufferedInputStream.read(ExtensibleBufferedInputStream.java:54)
    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:100)
    at org.teiid.core.util.ReaderInputStream.read(ReaderInputStream.java:94)
    at org.teiid.core.util.ObjectConverterUtil.write(ObjectConverterUtil.java:106)
    at org.teiid.core.util.ObjectConverterUtil.write(ObjectConverterUtil.java:143)
    at org.teiid.core.util.ObjectConverterUtil.write(ObjectConverterUtil.java:139)
    at org.teiid.jboss.rest.TeiidRSProvider.write(TeiidRSProvider.java:72)
    at org.jboss.resteasy.plugins.providers.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:32)
    at org.jboss.resteasy.plugins.providers.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:17)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:131)
    at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:60)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:120)
    at org.jboss.resteasy.security.doseta.DigitalSigningInterceptor.aroundWriteTo(DigitalSigningInterceptor.java:145)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124)
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:100)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124)
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:98)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:466)
    ... 33 more   

我找到了解决方案。正如@ramesh 提到的,我尝试了 Jdbc 客户端。但问题依然存在。 对于我们从 REST API 检索到的 XML 和 JSON 格式响应,此问题仍然存在。 这仅在响应大小大于 4000 个字符时发生,这是 teiid 的默认限制。我使用管理控制台从系统属性中增加了这个限制并重新启动了 teiid 集群。

property                     value    boot-time
org.teiid.maxStringLength    200000   true

这解决了这个空缓存响应问题。