in dubbo-rpc-extensions/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/resteasy/filter/DubboContainerResponseContextImpl.java [326:390]
public synchronized void filter() throws IOException {
while (currentFilter < responseFilters.length) {
ContainerResponseFilter filter = responseFilters[currentFilter++];
try {
suspended = false;
throwable = null;
inFilter = true;
filter.filter(requestContext, this);
} catch (IOException e) {
throw new ApplicationException(e);
} finally {
inFilter = false;
}
if (suspended) {
if (!request.getAsyncContext().isSuspended()) {
request.getAsyncContext().suspend();
weSuspended = true;
}
// ignore any abort request until we are resumed
filterReturnIsMeaningful = false;
return;
}
if (throwable != null) {
// handle the case where we've been suspended by a previous filter
if (filterReturnIsMeaningful) SynchronousDispatcher.rethrow(throwable);
else {
writeException(throwable);
return;
}
}
}
// here it means we reached the last filter
// some frameworks don't support async request filters, in which case suspend() is forbidden
// so if we get here we're still synchronous and don't have a continuation, which must be in
// the caller
if (continuation == null) return;
// if we've never been suspended, the caller is valid so let it handle any exception
if (filterReturnIsMeaningful) {
continuation.run();
onComplete.accept(null);
return;
}
// if we've been suspended then the caller is a filter and have to invoke our continuation
// try to write it out
try {
continuation.run();
onComplete.accept(null);
if (weSuspended) {
// if we're the ones who turned the request async, nobody will call complete() for us, so we have to
HttpServletRequest httpServletRequest =
(HttpServletRequest) contextDataMap.get(HttpServletRequest.class);
httpServletRequest.getAsyncContext().complete();
}
} catch (IOException e) {
logger.error(
"",
"Dubbo container response context filter error",
"request method is: " + request.getHttpMethod() + "and request uri is:"
+ request.getUri().getPath(),
"",
e);
}
}