当struts.ognl.allowStaticMethodAccess为false时,Struts 2调用静态方法

时间:2016-10-05 13:25:33

标签: java reflection struts2 ognl valuestack

为了解决安全问题,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方法,并使用相同的签名。

有没有更好的方法来避免这些样板吸气剂?!

1 个答案:

答案 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;
}

在JSP

<s:if test="!stringUtil.isEmpty(message)">
  <h2><s:property value="message"/></h2>
</s:if>