I have an endpoint which return a ResponseBodyEmitter:
@GetMapping("/foo/stream")
public ResponseEntity<ResponseBodyEmitter> getFoos() {
ResponseBodyEmitter rbe = new ResponseBodyEmitter();
executor.execute(() -> {
try {
rbe.send(foo1);
Thread.sleep(2000);
rbe.send(foo2);
Thread.sleep(2000);
rbe.send(foo3);
Thread.sleep(2000);
}
rbe.complete();
} catch (Exception ex) {
rbe.completeWithError(ex);
}
});
return ResponseEntity.ok(rbe);
}
A custom filter (FooValidationFilter) is created to perform checks on foo's object when this endpoint is called:
@Slf4j
@AllArgsConstructor
public class FooValidationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
ContentCachingRequestWrapper requestToCache = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper responseToUse = new ContentCachingResponseWrapper(response);
filterChain.doFilter(request, responseToUse);
if (!responseToUse.isCommitted() &&
responseToUse.getStatus() >= 200 && responseToUse.getStatus() < 300 &&
HttpMethod.GET.matches(request.getMethod())) {
Scanner scanner = new Scanner(responseToUse.getContentInputStream());
String fooField;
do {
fooField = scanner.findWithinHorizon(REGEX, 0);
// perform some checks
} while (fooField != null);
}
if (requestToCache.isAsyncStarted()) {
requestToCache.getAsyncContext().addListener(new AsyncListener() {
public void onComplete(AsyncEvent asyncEvent) throws IOException {
responseToUse.copyBodyToResponse();
}
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
}
public void onError(AsyncEvent asyncEvent) throws IOException {
}
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
}
});
} else {
responseToUse.copyBodyToResponse();
}
}
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return false;
}
Note:
In debug mode, the
FooValidationFilteris called after eachResponseBodyEmitter.send().In normal mode, the
FooValidationFilteris invoked only one time. So, the checks on some Foo objects will be bypassed.
Am I missing something which is causing this issue ?








