Java Groovy在脚本基类中调用意外的“get(String)”方法

Java Groovy在脚本基类中调用意外的“get(String)”方法,java,groovy,groovyshell,Java,Groovy,Groovyshell,我有一个小程序,可以让用户执行任意的Groovy代码。我使用一个基本的groovy.lang.Script类,该类提供了许多方法,其中一个名为get。所有这些代码都是用Java编写的 基类: 上面的getString方法是httpmethod=GET的别名 Groovy shell调用: 我找不到任何解释来解释为什么调用这个方法,也许我遗漏了一些文档段落 问题是: 为什么Groovy在脚本引用绑定中未定义的变量时调用ScriptClass.getString? 如果此行为是标准/正确的,是否有方

我有一个小程序,可以让用户执行任意的Groovy代码。我使用一个基本的groovy.lang.Script类,该类提供了许多方法,其中一个名为get。所有这些代码都是用Java编写的

基类:

上面的getString方法是httpmethod=GET的别名

Groovy shell调用:

我找不到任何解释来解释为什么调用这个方法,也许我遗漏了一些文档段落

问题是:

为什么Groovy在脚本引用绑定中未定义的变量时调用ScriptClass.getString? 如果此行为是标准/正确的,是否有方法防止将未定义变量的解析路由到ScriptClass.getString?
实际上,get方法干扰了groovy的元编程能力。看见Quote:当你重载get时,你失去了propertyMissing功能

在您的示例中,始终对模板进行求值。模板为no时,脚本返回no,这是在绑定中定义的。当模板为yes时,将计算未绑定变量yes,如果未绑定,通常会导致调用get和propertyMissing,但会中断,因为get在脚本中被重写


对于脚本中的get,您必须使用不同的方法名。

不知道脚本如何返回除null以外的任何内容,因为它只从其run方法返回null。如果您解析是或否,您会期望什么?通常,您会为脚本的上下文解析某种类型的DSL、好的、有意义的groovy代码。也许问题中遗漏了什么?@chriopp这是一个简化版本,只是为了重现问题。实际代码更复杂;但这又重现了错误。实际的脚本不仅仅是读取yes和no变量。谢谢,这为我指明了正确的方向。将propertyMissingString添加到基类中,并在基类中抛出MissingPropertyException,可以防止进一步调用未定义的变量,这就是我要寻找的。
import groovy.lang.Script;
public class ScriptClass extends Script {

    @Override
    public Object run() {
        return null;
    }

    //many other methods

    public String get(String uri) {
        System.out.println("get called with '" + uri + "'");
        return uri;
    }
}
public static void main(String[] args) throws Exception {
    CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
    compilerConfiguration.setScriptBaseClass(ScriptClass.class.getName());

    GroovyShell groovyShell = new GroovyShell(compilerConfiguration);

    Map<String, Object> map = new HashMap<>();
    map.put("no", "NO");

    String template = "yes";
    Script script = groovyShell.parse(template);
    script.setBinding(new Binding(map));

    Object res = script.run();
    System.out.println(res);
}
String template = "no";