前言
有这样一种场景,某些代码存在多层封装而只对外暴露一个调用API。但要考虑调用者绕过这个API调用的可能。
模拟工具类
public class ThreadUtils {
public static String hello() {
return "Hello";
}
}
模拟调用者
public class TestA {
public static void main(String[] args) {
System.out.println(ThreadUtils.hello());
}
}
public class TestB {
public static void main(String[] args) {
System.out.println(ThreadUtils.hello());
}
}
增加判断
考虑通过增加一个isAuth
方法,来控制调用
public static String hello() throws Exception {
if (!isAuth()) {
throw new Exception("NOT ALLOW!");
}
return "Hello";
}
private static boolean isAuth() {
return false;
}
Java Thread getStackTrace()方法
方法返回一个代表该线程的堆栈转储堆栈跟踪元素的数组。
这将返回一个零长度数组,如果该线程尚未启动或已经终止。如果返回的数组是非零长度则该数组的第一个元素代表堆栈,这是该序列中的最新的方法调用的顶部。所述阵列的最后一个元素代表堆栈,这是该序列中的至少最近的方法调用的底部。
所以
private static boolean isAuth() {
Thread thread = Thread.currentThread();
StackTraceElement[] stackTrace = thread.getStackTrace();
for (int i = 3; i < stackTrace.length; i++) {
if (allow.contains(stackTrace[i].getClassName())) {
return true;
}
}
return false;
}
效果展示
TestA.java执行
Hello
Process finished with exit code 0
TestB.java执行
Exception in thread "main" java.lang.Exception: NOT ALLOW!
at com.rice.util.ThreadUtils.hello(ThreadUtils.java:18)
at com.rice.test.TestB.main(TestB.java:11)
Process finished with exit code 1