Spring MVC未记录错误stackTrace

irtuqstp  于 2023-03-16  发布在  Spring
关注(0)|答案(3)|浏览(143)

我有一个spring mvc 4. 3应用程序。
我定义了一个简单Map异常解析器

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

发生异常时,将显示包含错误消息和堆栈跟踪的默认页面。
但在日志文件中我只有一行:

WARN  http-nio-9090-exec-13 uncaughtException - Resolved exception caused by handler execution: java.lang.NullPointerException

stackTrace不存在,这使得很难知道崩溃的位置(并且在生产中,错误页面上的堆栈跟踪不显示)。
我找到了Spring的日志记录位置(在AbstractHandlerExceptionResolver中):

protected void logException(Exception ex, HttpServletRequest request) {
        if (this.warnLogger != null && this.warnLogger.isWarnEnabled()) {
            this.warnLogger.warn(buildLogMessage(ex, request));
        }
    }

    
protected String buildLogMessage(Exception ex, HttpServletRequest request) {
    return "Resolved exception caused by handler execution: " + ex;
}

而且不包括stackTrace,因此无法执行此操作...
我如何让Spring记录堆栈跟踪(在html视图和日志文件中)?

qxgroojn

qxgroojn1#

问题中的代码使用了SimpleMappingExceptionResolver类,这是一个Spring框架类,但它是公共的,可以扩展。

建议的解决方案

将上面的类扩展为MyExceptionResolver并覆盖 logException 方法,如下所示:

protected String buildLogMessage(Exception ex, HttpServletRequest request) {
    return "Resolved exception caused by handler execution: " + ex.printStackTrace();
}

相应地调整XML配置。

<bean id="MyExceptionResolver" ...
af7jpaap

af7jpaap2#

好的,我找到了一个简单的解决方案,只需覆盖SimpleMappingExceptionResolver

public class MySimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {
    
    private Logger log;

    @Override
    protected void logException(Exception ex, HttpServletRequest request) {
        //super.logException(ex, request);
        log.error(ex.getMessage(),ex);
    }

    @Override
    public void setWarnLogCategory(String loggerName) {     
        super.setWarnLogCategory(loggerName);
        log=LoggerFactory.getLogger(loggerName);
    }

}

然后我使用我自己的实现,在那里我可以按照自己的意愿进行日志记录。

sqxo8psd

sqxo8psd3#

不要将异常添加到字符串中,而是将异常作为参数传递给logger方法。
当您使用“+”将异常连接到字符串中时,您将对异常调用toString方法,该方法将返回您在方法中看到的名称。
如果您这样做,它将记录堆栈跟踪,如您所愿:

warnLogger.warn("Resolved exception caused by handler execution:", ex);

相关问题