我正在向JaxRs注释服务添加Swagger注释。
我有以下内容:
(^{
GET true
Path "/{who}"
ApiOperation {:value "Get a hello" :notes "simple clojure GET"}
Produces ["text/plain; charset=UTF-8"]
ApiResponses {:value [(ApiResponse {:code 200 :message "yay!"})]}
}
如果我对生成的类进行反编译,注释看起来像这样:
@ApiResponses({@com.wordnik.swagger.annotations.ApiResponse(code=200L, message="yay!")})
@Produces({"text/plain; charset=UTF-8"})
@ApiOperation(value="Get a hello", notes="simple clojure GET")
@Path("/{who}")
@GET(true)
注意在第一个注释代码= 200L
在运行时期间,此值必须为int,我无法弄清楚如何实现此目的
如果我尝试
ApiResponses {:value [(ApiResponse {:code (int 200) :message "yay!"})]}
我收到编译错误(使用maven swagger插件)
Exception in thread "main" java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class, compiling:(pocclj/resourceclj.clj:14)
我试过了
(def success (int 200))
...
ApiResponses {:value [(ApiResponse {:code success :message "yay!"})]}
产生此编译错误:
Exception in thread "main" java.lang.IllegalArgumentException: Unsupported annotation value: success of class class java.lang.Integer, compiling:(pocclj/resourceclj.clj:14)
我尝试过其他一些东西(deref等)但是找不到秘密酱。
我对clojure很新,并且迫切需要一些帮助。
提前致谢
马丁
答案 0 :(得分:0)
您正确设置':code'的类型。哪个可以独立测试:
user> (def something ^{:ApiResponses {:code (int 200) :message "yay!"}} {:some :data :goes :here})
#'user/something
user> (meta something)
{:ApiResponses {:code 200, :message "yay!"}}
user> (-> (meta something) :ApiResponses :code type)
java.lang.Integer
如果没有强制转换,元数据包含错误的类型:
user> (def something-wrong ^{:ApiResponses {:code 200 :message "yay!"}} {:some :data :goes :here})
#'user/something-wrong
user> (meta something)
{:ApiResponses {:code 200, :message "yay!"}}
user> (-> (meta something-wrong) :ApiResponses :code type)
java.lang.Long
从异常看起来,对ApiResponse
的调用可能正在崩溃。如果ApiResponse是一个期望数字而不是s表达式的宏,那么我可以看到它没有正确处理它。如果它是一个函数,你需要调查它崩溃的原因。
如果我为ApiResponse提供存根实现,那么它适用于我:
user> (definterface Fooi (Something []))
user.Fooi
user> (def ApiResponse identity)
#'user/ApiResponse
user> (deftype Foo []
Fooi
(Something
^{GET true
Path "/{who}"
ApiOperation {:value "Get a hello" :notes "simple clojure GET"}
Produces ["text/plain; charset=UTF-8"]
ApiResponses {:value [(ApiResponse {:code (int 200) :message "yay!"})]}}
[this] (identity this)))
user.Foo
答案 1 :(得分:0)
我真的不知道ApiResponse,或者很多关于注释的内容,但是:看起来有些宏(deftype?
)正在为你生成注释,你需要它来看200
INT。 Clojure没有int
文字,因此将Integer对象直接传递给宏的唯一方法是通过调用它的其他宏。真的不可能以一种很好的方式做到这一点;据我所知,你必须使用eval
,或者通过专门针对int文字来缩小范围。这是解决方案的草图:
user> (use 'clojure.walk)
user> (defmacro with-int-literals [named-ints & body]
(prewalk-replace (into {}
(for [[k v] (partition 2 named-ints)]
[k (int v)]))
`(do ~@body)))
user> (map class (second (macroexpand-1 '(with-int-literals [x 100, y 200] [x y]))))
(java.lang.Integer java.lang.Integer)
因此,如果用deftype
形式包装整个with-int-literals
(或任何生成这些注释的宏),您可以为它生成整数而不是long。我实际上并不知道这会起作用;或许注释处理器中的某些东西由于某种原因从根本上无法处理整数。但至少通过这种方式,你可以提供它并希望最好。
由于您实际上需要元数据中的int文字,而不是“普通”代码,prewalk
实际上不会查看您关注的数据。您必须编写一个walk
版本,以合理的方式处理元数据,然后使用它而不是在这里预走。