2012-05-17 2 views
4

A назад, Крис Грейнджер отправил this middleware, чтобы получить хэш JSON, чтобы появиться в параметрах defpage под элементом «позвоночника» зонтика.Как получить данные JSON post в Noir

(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

Есть две вещи, которые вы можете сделать. Один из вариантов - заменить значение :params на карту, полученную после разбора JSON. Для этого просто сопоставьте новую карту с ключом :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

Я знаю, что это старый, но разве вы не можете использовать 'body-params' для него с lib-noir? –

0

Получил его. assoc просто работает для одного элемента, поэтому вам нужно поставить все под зонтиком :backbone. Чтобы нажать все элементы JSON в параметры, вы должны использовать merge. Таким образом, изменение 4-ю строчку в:

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

или (update-in req [: params] (частичное слияние (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.