[英]correctly printstacktrace of servlet exception
所以我使用過濾器來捕獲servlet異常(因為我們使用混合的jsf / plain servlets)
當捕獲ServletException並調用printstacktrace時,大部分信息都會丟失。
“真正的”根異常似乎隱藏在“有趣”的表達背后
((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause()
這顯然不是這樣做的方法。
是打印此類例外的“完整”信息的簡便方法。 有人可以解釋一下為什么異常這樣包裹?
從commons-lang看一下ExceptionUtils類。 它包含幾種用於打印整個異常鏈的有用方法。
在我看了ExceptionUtils之后,這解決了這個問題!
final StringWriter stacktrace = new StringWriter();
ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace));
msg.append(stacktrace.getBuffer());
這會打印出完整的堆棧跟蹤,其中包含相關的每條信息。
這稱為異常鏈接 。 通過將異常包裝在另一個異常中,您可以讓異常在堆棧中冒泡,而不會讓主應用程序類擔心某些低級異常。
例:
public void doStuff() throws StuffException {
try {
doDatabaseStuff();
} catch (DatabaseException de1) {
throw new StuffException("Could not do stuff in the database.", de1);
}
}
這樣,您的應用程序只需處理StuffException
但如果確實需要,它可以訪問底層的DatabaseException
。
要了解您捕到的異常的最底層(和所有其他)異常,可以對其根本原因進行迭代:
...
} catch (SomeException se1) {
Throwable t = se1;
logger.log(Level.WARNING, "Top exception", se1);
while (t.getCause() != null) {
t = t.getCause();
logger.log(Level.WARNING, "Nested exception", t);
}
// now t contains the root cause
}
ServletException的異常鏈接很棘手。 根據所使用的Web服務器實現和Web開發框架,在運行時鏈可能使用cause和/或rootCause。 這個鏈接很好地解釋了它。 為了使事情復雜化,我看到了異常,其中的原因指向異常本身。 這是我們使用的一個遞歸方法,它涵蓋了ServletExceptions的所有基礎:
public static Throwable getDeepCause(Throwable ex) {
if (ex == null) {
return ex;
}
Throwable cause;
if (ex instanceof ServletException) {
cause = ((ServletException) ex).getRootCause();
if (cause == null) {
cause = ex.getCause();
}
} else {
cause = ex.getCause();
}
if (cause != null && cause != ex) {
return getDeepCause(cause);
} else {
// stop condition - reached the end of the exception chain
return ex;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.