thymeleaf 3.0.15
在thymeleaf模板中通过${session.SPRING_SECURITY_LAST_EXCEPTION.getMessage()}获取异常消息时报错
Caused by: org.springframework.expression.EvaluationException: Calling methods is forbidden for type ‘java.lang.RuntimeException’ in Thymeleaf expressions. Blacklisted classes are: [java.util.concurrent.RunnableFuture, java.util.concurrent.Executor, java.lang.Runtime, java.util.concurrent.FutureTask, java.util.concurrent.ListenableFuture, java.lang.Runnable, java.util.concurrent.Future, java.lang.Thread, java.lang.reflect.Executable, java.lang.Class, java.lang.ClassLoader, java.sql.DriverManager].
在thymeleaf 3.0.15中将java.lang.Runtime前缀的类加入了黑名单不允许在模板中访问
异常以Exception抛出不要以RuntimeException抛出,其他类似问题通解
org.thymeleaf.spring5.expression.ThymeleafEvaluationContext
static final class ThymeleafEvaluationContextACLMethodResolver extends ReflectiveMethodResolver {
ThymeleafEvaluationContextACLMethodResolver() {
super();
}
@Override
public MethodExecutor resolve(
final EvaluationContext context, final Object targetObject,
final String name, final List<TypeDescriptor> argumentTypes) throws AccessException {
final Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
// 判断对象是否时允许访问的类型
if (!ExpressionUtils.isTypeAllowed(type.getName())) {
// We will only specifically allow calling "Object.getClass()" and "Class.getName()"
if (!(Class.class.equals(type) && "getName".equals(name))
&& !(Object.class.equals(type) && "getClass".equals(name))) {
throw new EvaluationException(
String.format(
"Calling methods is forbidden for type '%s' in Thymeleaf expressions. " +
"Blacklisted classes are: %s.",
type.getName(), ExpressionUtils.getBlacklist()));
}
}
return super.resolve(context, targetObject, name, argumentTypes);
}
}
public final class ExpressionUtils {
// 所有黑名单类名前缀
private static final Set<String> BLOCKED_CLASS_NAME_PREFIXES =
new HashSet<String>(Arrays.asList(
"java.lang.Runtime", "java.lang.Thread", "java.lang.Class", "java.lang.ClassLoader",
"java.lang.Runnable", "java.lang.reflect.Executable",
"java.util.concurrent.Future", "java.util.concurrent.FutureTask",
"java.util.concurrent.RunnableFuture", "java.util.concurrent.ListenableFuture",
"java.util.concurrent.Executor",
"java.sql.DriverManager"));
public static boolean isTypeAllowed(final String typeName) {
Validate.notNull(typeName, "Type name cannot be null");
final int i0 = typeName.indexOf('.');
if (i0 >= 0) {
final String package0 = typeName.substring(0, i0);
if ("java".equals(package0)) { // This is the only prefix that might be blocked
for (final String prefix : BLOCKED_CLASS_NAME_PREFIXES) {
if (typeName.startsWith(prefix)) {
return false;
}
}
}
}
return true;
}
public static List<String> getBlockedClasses() {
final List<String> blocked = new ArrayList<String>();
blocked.addAll(BLOCKED_CLASS_NAME_PREFIXES);
return blocked;
}
private ExpressionUtils() {
super();
}
}
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有