出于安全考虑,struts2将struts.ognl.allowStaticMethodAccess
设置为false
。静态方法调用在某些情况下可能是有用的,例如,当处理基于表达式的验证器struts2时,在验证器的扩展中使用StringUtils。
Math
类,我们应该在下面添加:
public double randomMath(){
return Math.random();
}
public double asinMath(double a){
return Math.asin(a);
}
....
用作${randomMath}
或${asinMath(1)}
可以看到,对于Math
类中的每个方法,我们都需要在action中定义一个具有相同签名的public
方法。
有没有更好的方法来避免这些样板getter ?!
OGNL允许执行方法,但默认情况下禁用静态访问,因此不能在表达式中使用静态方法。但是,您可以教OGNL哪些类需要访问静态方法。
OGNL开发者指南:方法访问器
方法调用是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()
在逐个类的基础上设置方法访问器。this是Object的默认方法访问器(它只是根据方法名称和参数类型找到一个合适的方法,并使用反射来调用该方法)。
你可以写一些
public class StringUtil extends StringUtils implements MethodAccessor {
//implement above methods
}
<标题> Action类
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;
}
在JSP
<s:if test="!stringUtil.isEmpty(message)">
<h2><s:property value="message"/></h2>
</s:if>
标题>