[update] StrUtil.printStackTrace 获取异常堆栈优化
Some checks failed
yexuejc-base package jre11 / package_job (push) Failing after 38s

This commit is contained in:
maxf
2025-09-29 18:19:33 +08:00
parent 78ca6885c5
commit 80072eac11

View File

@@ -1,20 +1,27 @@
package com.yexuejc.base.util; package com.yexuejc.base.util;
import com.yexuejc.base.constant.ExpCode;
import com.yexuejc.base.exception.BaseException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.yexuejc.base.constant.ExpCode;
import com.yexuejc.base.exception.BaseException;
/** /**
* 字符串工具类 * 字符串工具类
* *
@@ -25,12 +32,12 @@ import java.util.regex.Pattern;
*/ */
public final class StrUtil { public final class StrUtil {
private static final Logger logger = Logger.getLogger(StrUtil.class.getName()); private static final Logger logger = Logger.getLogger(StrUtil.class.getName());
private StrUtil() { private StrUtil() {
} }
private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
// ThreadLocal缓存MessageDigest实例提高性能 // ThreadLocal缓存MessageDigest实例提高性能
private static final ThreadLocal<MessageDigest> MD5_DIGEST = ThreadLocal.withInitial(() -> { private static final ThreadLocal<MessageDigest> MD5_DIGEST = ThreadLocal.withInitial(() -> {
try { try {
@@ -39,7 +46,7 @@ public final class StrUtil {
throw new RuntimeException(new BaseException(e, ExpCode.MD5_ALGORITHM_UNAVAILABLE)); throw new RuntimeException(new BaseException(e, ExpCode.MD5_ALGORITHM_UNAVAILABLE));
} }
}); });
private static final ThreadLocal<MessageDigest> SHA256_DIGEST = ThreadLocal.withInitial(() -> { private static final ThreadLocal<MessageDigest> SHA256_DIGEST = ThreadLocal.withInitial(() -> {
try { try {
return MessageDigest.getInstance("SHA-256"); return MessageDigest.getInstance("SHA-256");
@@ -47,7 +54,7 @@ public final class StrUtil {
throw new RuntimeException(new BaseException(e, ExpCode.SHA256_ALGORITHM_UNAVAILABLE)); throw new RuntimeException(new BaseException(e, ExpCode.SHA256_ALGORITHM_UNAVAILABLE));
} }
}); });
// 使用SecureRandom替代Random提高安全性 // 使用SecureRandom替代Random提高安全性
private static final ThreadLocal<SecureRandom> SECURE_RANDOM = ThreadLocal.withInitial(SecureRandom::new); private static final ThreadLocal<SecureRandom> SECURE_RANDOM = ThreadLocal.withInitial(SecureRandom::new);
@@ -65,8 +72,7 @@ public final class StrUtil {
return ((Optional<?>) obj).isEmpty(); return ((Optional<?>) obj).isEmpty();
} else if (obj instanceof CharSequence) { } else if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0; return ((CharSequence) obj).length() == 0;
} else if (obj.getClass() } else if (obj.getClass().isArray()) {
.isArray()) {
return Array.getLength(obj) == 0; return Array.getLength(obj) == 0;
} else if (obj instanceof Collection) { } else if (obj instanceof Collection) {
return ((Collection<?>) obj).isEmpty(); return ((Collection<?>) obj).isEmpty();
@@ -85,9 +91,7 @@ public final class StrUtil {
* @return * @return
*/ */
public static String genUUID() { public static String genUUID() {
return UUID.randomUUID() return UUID.randomUUID().toString().replaceAll("-", "");
.toString()
.replaceAll("-", "");
} }
/** /**
@@ -122,9 +126,7 @@ public final class StrUtil {
* @return * @return
*/ */
public static String genNum() { public static String genNum() {
int hashCode = UUID.randomUUID() int hashCode = UUID.randomUUID().toString().hashCode();
.toString()
.hashCode();
StringBuilder num = new StringBuilder(); StringBuilder num = new StringBuilder();
if (hashCode < 0) { if (hashCode < 0) {
hashCode = -hashCode; hashCode = -hashCode;
@@ -132,8 +134,7 @@ public final class StrUtil {
} else { } else {
num.append("1"); num.append("1");
} }
return num.append(String.format("%010d", hashCode)) return num.append(String.format("%010d", hashCode)).substring(0, 8);
.substring(0, 8);
} }
/** /**
@@ -183,13 +184,13 @@ public final class StrUtil {
* @return SHA256值 * @return SHA256值
*/ */
public static String toSHA256(final String str) { public static String toSHA256(final String str) {
return toSHA(str, "SHA-256"); return toSHA(str, "SHA-256");
} }
/** /**
* SHA加密 * SHA加密
* *
* @param str 要加密的字符串 * @param str 要加密的字符串
* @param algorithm 算法名称 * @param algorithm 算法名称
* @return SHA值 * @return SHA值
*/ */
@@ -340,10 +341,7 @@ public final class StrUtil {
for (String key : keys) { for (String key : keys) {
Object value = sortedParams.get(key); Object value = sortedParams.get(key);
if (isNotEmpty(key) && isNotEmpty(value)) { if (isNotEmpty(key) && isNotEmpty(value)) {
content.append(index == 0 ? "" : "&") content.append(index == 0 ? "" : "&").append(key).append("=").append(value);
.append(key)
.append("=")
.append(value);
++index; ++index;
} }
} }
@@ -464,17 +462,14 @@ public final class StrUtil {
if (cause != null) { if (cause != null) {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
if (isNotEmpty(cause.getMessage())) { if (isNotEmpty(cause.getMessage())) {
msg.append(cause.getMessage()) msg.append(cause.getMessage()).append(NEW_LINE);
.append(NEW_LINE);
} }
String causedMsg = printStackTrace(cause, (eMessage) -> { String causedMsg = printStackTrace(cause, (eMessage) -> {
if (isNotEmpty(eMessage)) { if (isNotEmpty(eMessage)) {
msg.append(eMessage) msg.append(eMessage).append(NEW_LINE);
.append(NEW_LINE);
} }
}); });
return msg.append(causedMsg) return msg.append(causedMsg).toString();
.toString();
} }
return ""; return "";
} }
@@ -493,30 +488,24 @@ public final class StrUtil {
private static String printStackTrace(Throwable cause, Consumer<String> consumer) { private static String printStackTrace(Throwable cause, Consumer<String> consumer) {
if (cause != null) { if (cause != null) {
String err = "\tat %s.%s(%s.java:%d)";
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String cClass = cause.getClass() String cClass = cause.getClass().getName();
.getName();
String eMessage = cause.getMessage(); String eMessage = cause.getMessage();
StackTraceElement[] stackTrace = cause.getStackTrace(); StackTraceElement[] stackTrace = cause.getStackTrace();
Throwable caused = cause.getCause(); Throwable c = cause.getCause();
while (caused != null) { while (c != null) {
cClass = caused.getClass() cClass = c.getClass().getName();
.getName(); eMessage = c.getMessage();
eMessage = caused.getMessage(); stackTrace = c.getStackTrace();
stackTrace = caused.getStackTrace(); c = c.getCause();
caused = caused.getCause();
consumer.accept(eMessage);
} }
sb.append("Caused by: ") sb.append("Caused by: ").append(cClass).append(": ").append(eMessage).append(System.lineSeparator());
.append(cClass)
.append(": ")
.append(eMessage)
.append(NEW_LINE);
for (StackTraceElement element : stackTrace) { for (StackTraceElement element : stackTrace) {
sb.append("\tat "); String className = element.getClassName();
sb.append(String.format(ERROR_MESSAGE_FORMAT, element.getClassName(), element.getMethodName(), element.getFileName(), String simpleClassName = className.substring(className.lastIndexOf('.') + 1);
element.getLineNumber())); sb.append(String.format(err, className, element.getMethodName(), simpleClassName, element.getLineNumber()))
sb.append(NEW_LINE); .append(System.lineSeparator());
} }
return sb.toString(); return sb.toString();
} }