jodd-madvoc/src/main/java/jodd/madvoc/MadvocServletFilter.java
@Override
	public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		String actionPath = DispatcherUtil.getServletPath(request);

		try {
			MadvocResponseWrapper madvocResponse = new MadvocResponseWrapper(response);

			actionPath = madvocController.invoke(actionPath, request, madvocResponse);
		} catch (Exception ex) {
			log.error("Invoking action path failed: " + actionPath, ex);

			throw new ServletException(ex);
		}
		if (actionPath != null) {	// action path is not consumed

			boolean pathProcessed = processUnhandledPath(actionPath, req, res);

			if (!pathProcessed) {
				chain.doFilter(request, response);
			}
		}
	}
@Override
	public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		String actionPath = DispatcherUtil.getServletPath(request);

		try {
			MadvocResponseWrapper madvocResponse = new MadvocResponseWrapper(response);

			actionPath = madvocController.invoke(actionPath, request, madvocResponse);
		} catch (Exception ex) {
			log.error("Invoking action path failed: " + actionPath, ex);

			throw new ServletException(ex);
		}
		if (actionPath != null) {	// action path is not consumed

			boolean pathProcessed = processUnhandledPath(actionPath, req, res);

			if (!pathProcessed) {
				chain.doFilter(request, response);
			}
		}
	}
Builds {@link ActionRequest} and invokes it. If action result is a chain, it repeats the process.