将Throwable.getStackTrace()的结果转换为描述堆栈跟踪的字符串最简单的方法是什么?
当前回答
对Gala的回答进行了详细分析,其中还将包括例外情况的原因:
private String extrapolateStackTrace(Exception ex) {
Throwable e = ex;
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
while (e.getCause() != null) {
e = e.getCause();
trace += "Cause by: " + e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
}
return trace;
}
其他回答
我不久前写了一些方法,所以我想为什么不花我的两分钱。
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
return stackTraceElementsToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
}
}
return str;
}
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
}
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
return throwableToStrNoStackTraces(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
return throwableToStrNoStackTraces(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStr(Throwable e) {
return throwableToStr(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
return throwableToStr(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = padding + e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
例子:
try(InputStream in = new FileInputStream(file)) {
...
} catch(IOException e) {
String exceptionToString = throwableToStr(e);
someLoggingUtility.println(exceptionToString);
...
}
打印:
java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.gmail.br45entei.Example.main(Example.java:32)
选项很少
StringWriter sw=新StringWriter();e.printStackTrace(新的PrintWriter(sw));字符串异常AsString=sw.toString();使用Google Guava libString stackTrace=Throwables.getStackTraceAsString(myException);org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(可丢弃)
Kotlin>=1.4
在Throwable上使用内置函数stackTraceToString()。
Kotlin<1.4
扩展Throwable类将提供String属性error.stackTraceString:
val Throwable.stackTraceString: String
get() {
val sw = StringWriter()
val pw = PrintWriter(sw)
this.printStackTrace(pw)
return sw.toString()
}
使用Throwable.printStackTrace(PrintWriter pw)将堆栈跟踪发送到适当的编写器。
import java.io.StringWriter;
import java.io.PrintWriter;
// ...
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);
我的oneliner将堆栈跟踪转换为封闭的多行字符串:
Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))
易于传递给记录器“原样”。
推荐文章
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?