InvocationImpl implements Invocation { @Override public Response proceed() throws Exception { if (controller.skipInterceptor || currentStack >= interceptors.size()) { logger.debug("execute controller, controller={}", controller.controllerInfo); Response response = controller.controller.execute(request); if (response == null) throw new Error("controller must not return null response, controller=" + controller.controllerInfo); return response; } else { Interceptor interceptor = interceptors.get(currentStack); currentStack++; logger.debug("intercept, interceptorClass={}", interceptor.getClass().getCanonicalName()); Response response = interceptor.intercept(this); if (response == null) throw new Error("interceptor must not return null response, interceptor=" + interceptor.getClass().getCanonicalName()); return response; } } InvocationImpl(ControllerHolder controller, List<Interceptor> interceptors, Request request, WebContextImpl context); @Override T annotation(Class<T> annotationClass); @Override WebContext context(); @Override Response proceed();  }
@Test void process() throws Exception { var stack = new Stack(); var controller = new TestController(stack, 3); List<Interceptor> interceptors = List.of(new TestInterceptor(stack, 0), new TestInterceptor(stack, 1), new TestInterceptor(stack, 2)); var invocation = new InvocationImpl(new ControllerHolder(controller, null, null, null, false), interceptors, request, new WebContextImpl()); Response response = invocation.proceed(); assertThat(response.status()).isEqualTo(HTTPStatus.NO_CONTENT); assertThat(controller.executed).isTrue(); for (Interceptor interceptor : interceptors) { assertThat(((TestInterceptor) interceptor).executed).isTrue(); } }
@Test void skipInterceptor() throws Exception { var stack = new Stack(); var controller = new TestController(stack, 0); List<Interceptor> interceptors = List.of(new TestInterceptor(stack, 0)); var invocation = new InvocationImpl(new ControllerHolder(controller, null, null, null, true), interceptors, request, new WebContextImpl()); Response response = invocation.proceed(); assertThat(response.status()).isEqualTo(HTTPStatus.NO_CONTENT); assertThat(controller.executed).isTrue(); for (Interceptor interceptor : interceptors) { assertThat(((TestInterceptor) interceptor).executed).isFalse(); } }