【问题标题】:Groovy DSL with Java使用 Java 的 Groovy DSL
【发布时间】:2014-12-05 11:39:04
【问题描述】:

自从我开始使用 Groovy 已经有几天了。但是随着所有的阅读和冲浪,我还没有完全弄清楚如何完成我的想法。所以,请原谅我是初学者。一如既往地感谢您的帮助。

我想要实现的是这个:我有一个 Java 类,比如 ServiceClass,它有一些方法(getMethod()postMethod() 等)来发出一些 REST GET/POST 请求(就其本身而言,它工作正常)。现在,我想公开一个 DSL,以便最终用户可以说类似:callService ServiceClass method getMethod 并且我执行了 ServiceClass.getMethod()

到目前为止,我一直在尝试的是:我在某处放置了一个 userCommand 文件,现在只显示:callService ServiceClass

我有一个 sample.groovy,现在就这样做:

class Sample {
    def srvc
    def callService(srvc) {
        this.srvc = srvc
        "Calling $srvc"
    }
}

我有一个integrator.groovy 文件,其中包含:

//necessary imports
class Integrator{
    def sample = new Sample()
    def binding = new Binding([
        sample:sample, 
        ServiceClass: new ServiceClass(), 
        callService:sample.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        shell.evaluate("userCommand")
    }
}

然后从我的 Java 应用程序运行它,我正在做:

public static void main(String[] args) {
    Integator i = new Integrator()
    i.runIt();
}

但这只是行不通。使用上面的语法它说:

线程“主”java.lang.NullPointerException 中的异常:无法在空对象上调用方法 setVariable()....

谁能告诉我如何传递参数和创建对象实例?

【问题讨论】:

  • 尝试时会发生什么? “不工作”并不能告诉我们您的问题是什么。
  • @bmargulies:添加了看到的错误信息。实际上,甚至不确定所采用的方法是否正确。所以希望有人指导我如何让整个工作正常。

标签: java groovy dsl


【解决方案1】:

更新:考虑以下userCommand 文件:

文件userCommand

callService ServiceClass getMethod

它将被 groovy 解析为callService(ServiceClass).getGetMethod()。所以你需要一个getProperty 方法,它将调用重新路由到正确的方法:

文件Dsl.groovy

class Dsl {
  static void main(args) {
      new Integrator().runIt()
  }
}

class DslDelegate {
    def service
    def callService(service) {
        this.service = service
        this
    }

    def getProperty(String prop) {
      if (prop == "getMethod") { service.getMethod() }
      else { throw new RuntimeException("Unrecognized property '$prop'") }
    }
}

class ServiceClass {
  def getMethod() { "serviceClass getMethod" }
}

class Integrator{
    def dslDelegate = new DslDelegate()
    def binding = new Binding([
        ServiceClass: new ServiceClass(), 
        callService:dslDelegate.&callService ])
    def shell = new GroovyShell(binding)

    def runIt() {
        assert shell.evaluate(new File("userCommand")) == 
            "serviceClass getMethod"
    }
}

注意我重命名了Sample 类,所以它成为ServiceClass 的委托人。现在它分离了 DSL/服务职责。

callService ServiceClass method getMethod 也可以,但需要更多代码。

【讨论】:

  • :谢谢,您上面建议的代码不会引发任何错误,但也不会真正调用“callService”。试过了,但它不打印“调用服务类”:(
  • 实际上,我通过使“userCommand”文件具有“.groovy”扩展名来实现这一点。实际上期望“userCommand”文件只是任何文本文件;但可能它不会那样工作。现在我已经开始了,想知道您是否可以指导我实现目标。也就是说,现在我想在我的'userCommand.groovy'中有类似“callService(ServiceName:ServiceClass,MethodName:getMethod)”的东西。我如何在我的“Integrator”中翻译它,以便在“callService”方法中我有“ ServiceClass.getMethod()"。
  • 上面的代码不应该打印,而是在runIt方法中有一个传递断言。尝试在this.srvc = srvc 之后添加打印,它应该可以工作。我的 userCommand 文件没有 groovy 扩展名
  • 还有一个请求 Will,你能帮我找到一些关于在 Groovy 中不使用点和括号的方法链接的材料/指南吗?一直在环顾四周,运气不佳
猜你喜欢
  • 2012-07-10
  • 1970-01-01
  • 2017-06-08
  • 2018-05-22
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多