为了解决安全问题,struts 2将struts.ognl.allowStaticMethodAccess
设置为false
。静态方法调用在某些情况下可能很有用,例如在处理表达式基础验证器Struts 2 using StringUtils in validator expersions时。
解决此问题的一种方法是在操作中定义一个辅助方法,例如,如果我们要使用Math
类,我们应该在下面添加:
public double randomMath(){
return Math.random();
}
public double asinMath(double a){
return Math.asin(a);
}
....
并将其用作${randomMath}
或${asinMath(1)}
正如您在Math
类中的每个方法所看到的,我们需要在操作中定义public
方法,并使用相同的签名。
有没有更好的方法来避免这些样板吸气剂?!
答案 0 :(得分:1)
OGNL允许执行方法,但默认情况下禁用静态访问,因此您不能在表达式中使用静态方法。但是,您可以教OGNL哪些类需要访问静态方法。
OGNL developer guide: Method Accessors
方法调用是OGNL需要根据动态信息查找方法的另一个领域。
MethodAccessor
接口提供了OGNL如何调用方法的钩子。当请求静态或实例方法时,调用此接口的实现者来实际执行该方法。public interface MethodAccessor { Object callStaticMethod( Map context, Class targetClass, String methodName, List args ) throws MethodFailedException; Object callMethod( Map context, Object target, String methodName, List args ) throws MethodFailedException; }
您可以使用
OgnlRuntime.setMethodAccessor()
逐个类地设置方法访问器。它是Object的默认方法访问器(它只是根据方法名称和参数类型找到合适的方法,并使用反射来调用方法)。
您可以编写代码
public class StringUtil extends StringUtils implements MethodAccessor {
//implement above methods
}
public static final String MESSAGE = "hello.message";
/**
* Field for Message property.
*/
private String message;
/**
* Return Message property.
*
* @return Message property
*/
public String getMessage() {
return message;
}
private StringUtil stringUtil = new StringUtil();
public StringUtil getStringUtil() {
return stringUtil;
}
public String execute() throws Exception {
setMessage(getText(MESSAGE));
OgnlRuntime.setMethodAccessor(StringUtil.class, stringUtil);
return SUCCESS;
}
<s:if test="!stringUtil.isEmpty(message)">
<h2><s:property value="message"/></h2>
</s:if>