2

POST 要求を受け取り、:malformed-decision で要求本文を検証し、:post!-decision で本文をデータベースに保存し、保存された本文を :handle-created に返すことになっている 1 つの defresource があります。

(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-function で 3 回読み取ります。1回目は機能しますが、2回目にslurpが呼び出されると、パラメータとしてnilが渡され、java.io.EOFException: JSONエラーが発生します。読者は前回残したところから読み始めると思います。

リクエストの本文を 3 回読むにはどうすればよいでしょうか。または、読み取りの結果を変数に保存し、それを他の解放者の決定に渡す良い方法はありますか?

4

1 に答える 1

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ます。

Liberator の実行モデルの詳細については、https://clojure-liberator.github.io/liberator/doc/execution-model.htmlを参照してください。

于 2015-07-12T19:10:02.193 に答える