2012-05-17 34 views
4

回過頭來,Chris Granger發佈了this middleware以使JSON哈希值出現在「骨幹」元素下的defpage params中。如何在Noir中獲取JSON發佈數據

(defn backbone [handler] 
    (fn [req] 
    (let [neue (if (= "application/json" (get-in req [:headers "content-type"])) 
     (update-in req [:params] assoc :backbone (json/parse-string (slurp (:body req)) true)) 
     req)] 
    (handler neue)))) 

我該如何修改此代碼以使JSON元素在defpage中顯示爲頂級參數;即擺脫:骨幹傘?

+0

你爲什麼要這樣?如果JSON對象中的任何數據覆蓋現有的請求屬性,看起來這可能是災難性的。除非那是你的目標? – Jeremy

+0

沒有其他請求屬性。所有內容都以JSON格式發佈。這就是爲什麼傘「骨幹」元素對我來說似乎多餘。 –

+0

啊,我看到它正在更新':params'鍵,而不是請求映射......查看我的答案。 – Jeremy

回答

3

你可以做兩件事。一種選擇是用解析JSON後返回的映射替換:params的值。爲了做到這一點,只需將新地圖關聯到:params鍵即可。

(assoc req [:params] (json/parse-string (slurp (:body req)) true)) 

(如由@dAni建議的)另一種選擇是所解析的JSON的值合併到這樣的:params地圖現有值不覆蓋。您需要使用partial而不是僅僅使用merge的原因是因爲最終地圖是從左到右地圖的合併結果。如果您希望JSON映射的值優先,您的解決方案就可以工作。

(update-in req [:params] 
    (partial merge (json/parse-string (slurp (:body req)) true))) 
+0

我知道這是舊的,但不能只用lib-noir使用'body-params'嗎? –

0

明白了。 assoc只適用於一個元素,所以你必須把所有東西放在:backbone的傘下。要將全部的JSON元素拖入參數,必須使用merge。因此,改變四號線到:

(update-in req [:params] merge (json/parse-string (slurp (:body req)) true)) 
+1

或(update-in req [:params](partial merge(json/parse-string(slurp(:body req))true)))如果您希望退出的參數不被覆蓋。 – DanLebrero

-1

如果你不介意另一依賴拉,你可以使用ring-middleware-format library.

說明:

  • 添加[ring-middleware-format "0.1.1"]project.clj

  • 然後在你的server.clj中加入下面的代碼:

代碼:

(:require [ring.middleware.format-params :as format-params]) 

(server/add-middleware format-params/wrap-json-params) 

(defn -main [& m] 
; Start the server... 
) 

現在,任何進入的JSON將可使用就像形式POSTDATA。