在Clojure中扩展Dropwizard服务类

时间:2012-01-26 21:48:35

标签: java rest clojure dropwizard

我一直在使用Dropwizard在Scala中编写RESTful API一段时间了,我真的很想在Clojure中使用它。

我要做的是创建一个com.yammer.dropwizard.Service的子类,我可以在我的-main中实例化并运行,我正在努力实现这一目标。

据我所知,我的选择是:

    {li> gen-classns声明中。不可行,因为我想构建宏(例如defservice),我无法在ns声明中使用。除非有某种方法可以在运行时生成一个东西并将其传递给compile,但这似乎是一个肮脏的黑客。 在gen-class之外
  1. ns。尽管some code I found,但似乎根本不起作用。这是一个简单的例子:

    user> (gen-class :name foo :extends Object)
    nil
    user> (foo.)
    Unable to resolve classname: foo
     [Thrown class java.lang.IllegalArgumentException]
    

    我知道gen-class仅在编译时有效。我把它放到一个文件中并将(foo.放到我的-main中,我得到了同样的例外。

  2. proxy。这似乎是最有希望的,它适用于简单的情况,但不适用于扩展Dropwizard的Service类:

    user> (proxy [Object] [])
    #<Object$0 user.proxy$java.lang.Object$0@249faafc>
    user> (import [com.yammer.dropwizard Service])
    com.yammer.dropwizard.Service
    user> (proxy [Service] ["x"])
    java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
      [Thrown class java.lang.ClassCastException]
    

    我认为这可能是由于Service采用了类型参数,但我找不到有关在Clojure中处理此问题的任何信息。我所发现的似乎表明这些只对javac有意义,而被Clojure忽略了。所以也许我对于为什么会发生这种情况不正确。

  3. deftype。不起作用,因为Service是一个类,deftype仅适用于接口和协议。

  4. 我认为我走在正确的轨道上,但我错过了gen-class和/或proxy如何工作的一些细微之处,而且Clojure文档非常简洁。如何在Clojure中扩展此Java类?

1 个答案:

答案 0 :(得分:0)

我会说使用选项1,但除非我误解你的描述,听起来你正试图在命名空间表单中编写代码?这不是你想要的。将gen-class添加到命名空间表单时,将为该整个命名空间生成一个Java类。然后,您可以通过使用-prefix在该ns中命名函数来覆盖方法(或者选择另一个并使用:method-prefix)。

这是一个例子。我不太了解你用这些类来测试它们的库,但它应该至少相似:

(ns com.myapp.MyService
  (:gen-class
   :extends com.yammer.dropwizard.Service
   :exposes-methods {someSuperClassMethod someLocalAlias}))

;; now just write your code as normal, note that
;; you can access super-class methods with the exposes-methods
;; map above!

;; prefix your overriden methods with -

(defn -overriddenMethod
  [params]
  ... )

希望有所帮助!