protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
            throws ServletException, IOException {
        Exception exception = existing;
        try {
            afterCompletion(request, response, exception);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Successfully invoked afterCompletion method.");
            }
        } catch (Exception e) {
            if (exception == null) {
                exception = e;
            } else {
                LOGGER.debug("afterCompletion implementation threw an exception.  This will be ignored to "
                        + "allow the original source exception to be propagated.", e);
            }
        }
        if (exception != null) {
            if (exception instanceof ServletException) {
                throw (ServletException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                if (LOGGER.isDebugEnabled()) {
                    String msg = "Filter execution resulted in an unexpected Exception "
                            + "(not IOException or ServletException as the Filter API recommends).  "
                            + "Wrapping in ServletException and propagating.";
                    LOGGER.debug(msg);
                }
                throw new ServletException(exception);
            }
        }
    }
Executes cleanup logic in the {@code finally} code block in the
{@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
     doFilterInternal(request, response, filterChain)}
implementation.
<p/>
This implementation specifically calls
{@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
as well as handles any exceptions properly.

@param request  the incoming {@code ServletRequest}
@param response the outgoing {@code ServletResponse}
@param existing any exception that might have occurred while executing the {@code FilterChain} or
                pre or post advice, or {@code null} if the pre/chain/post execution did not throw an {@code Exception}.
@throws ServletException if any exception other than an {@code IOException} is thrown.
@throws IOException      if the pre/chain/post execution throw an {@code IOException}
web/src/main/java/org/apache/shiro/web/servlet/AdviceFilter.java