Spring MVC does not register all exceptions

I have a Spring MVC setup for logging exceptions using public record keeping, but find that some exceptions are not logged at runtime.

Here is my bean configuration for the standard exception resolver provided by spring:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.Exception">error</prop>
        </props>
    </property>
</bean>
+5
source share
3 answers

To do this in order to log most exceptions, I had to add the following line to my configuration:

    <property name="warnLogCategory" value="someCategoryStringYouMakeUp" />

So in the end, it became as follows:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="warnLogCategory" value="apperror" />
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.Exception">error</prop>
        </props>
    </property>
</bean>

warnLogCategory is described in detail here .

+4
source

, @Brad Parks, HttpServlet, ( ), , Spring. , Spring, , , Spring Http-, SimpleMappingException Resolver (.. DispatchServlet Interceptors ).

, SimpleMappingExceptionResolver.

public class ExceptionLoggerServletFilter implements Filter {

    private CommonAccessLogFormatter requestFormat = new CommonAccessLogFormatter();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            StringBuilder sb = new StringBuilder("Very Bad shit has happened:");
            if (request instanceof HttpServletRequest)
                requestFormat.appendLogEntry((HttpServletRequest) request, sb);
            log.fatal(sb.toString(), e);
            throw new ServletException(e);
        }
    }

    @Override
    public void destroy() {
    }


    private static final Logger log = Logger.getLogger(ExceptionLoggerServletFilter.class);

}

, , , , , ( Tomcat JULI).

commons , Apache.

+3

In my test, use SimpleMappingExceptionResolveris not possible the log MissingServletRequestParameterException, I combine @ControllerAdviceand Filterfor logging.

Use ControllerAdviceto capture the Throwable raised in the Spring MVC controller.

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger("global_controller_exception_logger");

    @ExceptionHandler(value = Throwable.class)
    public void defaultErrorHandler(Throwable e) throws Throwable {
        // If the exception is annotated with @ResponseStatus rethrow it and let
        // the framework handle it.
        // AnnotationUtils is a Spring Framework utility class.
        if (AnnotationUtils.findAnnotation
                (e.getClass(), ResponseStatus.class) != null) {
            throw e;
        }

        // Otherwise log exception
        logger.error("global controller default exception handler", e);
        throw e;
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public void httpBadRequest(Exception e, HttpServletRequest request) throws Exception {
        StringBuffer requestURL = request.getRequestURL();
        logger.warn("{}   HTTP Status 400 - {}", requestURL, e.getMessage());
        throw e;
    }
}

Use Filterto catch an additional exception.

@WebFilter(
        filterName = "ExceptionLogFilter",
        urlPatterns = "/*",
        dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR}
)
public class ExceptionLogFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger("global_filter_exception_logger");


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } catch (IOException | ServletException e) {
            logger.error("bad thing happened during doFilter", e);
            throw e;
        }
    }

    ......
}

log configuration

<logger name="global_controller_exception_logger" level="info"/>

<logger name="global_filter_exception_logger" level="info"/>

You can view my gist for full code.

+1
source

All Articles