2015-07-12 72 views
2

我有一个defresource,这应该采取POST请求,验证请求主体:malformed-decision,将主体保存到数据库中:post!-decision并返回保存的主体in:手柄创建。多个clojure解放者的决定读取请求主体

(defn parse-project [context] (json/read-str 
           (slurp (get-in context [:request :body])) 
           :key-fn keyword))  
(defresource add-new-project 
     :malformed? (fn[ctx] (not (project-is-valid (parse-project ctx)))) 
     :handle-malformed (fn [_] (generate-string (str "Malformed json!"))) 
     ... 
     :post! (fn [ctx] (save-to-db (parse-project ctx)) 
     :handle-created (fn [ctx] (... parse-project ...)) 

所以我的代码读取三次ByteArrayInputStream(来自:request:body)与slurp函数。第一次工作,但第二次调用slurp时,nil作为参数传递并出现java.io.EOFException:JSON错误。我认为读者开始阅读上次留下的位置。

我怎样才能读取请求的正文三次?或者,有没有很好的方法可以将阅读结果保存到变量中并将其传递给其他解放者决策?

回答

3

context可以根据每个决定和行动功能的结果进行更新。您可以在malformed?中解析项目一次,并返回一个包含解析项目的地图,该项目将被合并到上下文中,以便它可用于以下决策和操作。例如:

(defresource add-new-project 
    :malformed? (fn[ctx] (let [project (parse-project ctx)] 
         (when (project-is-valid project) 
          {:project project}))) 
    :handle-malformed (fn [_] (generate-string (str "Malformed json!"))) 
    :post! (fn [ctx] (save-to-db (:project ctx))) 
    :handle-created (fn [ctx] (do-something (:project ctx)))) 

如果该项目是有效的,:malformed?返回在未来的决策和行动中使用的{:project project}地图将被合并为背景。 如果项目无效,它将返回nil,因此执行继续在:handle-malformed。请参阅https://clojure-liberator.github.io/liberator/doc/execution-model.html