Как я высмеиваю JSON сообщение в ринге?
Я использую перидот - https://github.com/xeqi/peridot для тестирования моего кольцевого приложения, и он работает нормально, пока не попробую смоделировать почтовый запрос с данными json:
(требуется '[cheshire.core:as json]) (используйте 'compojure.core) (defn JSON-Post [Req] (если (: требование к телу) (json / parse-string (slurp (:body req))))) (размораживает все маршруты (POST "/test/json" req (json-response (json-post req)))) (def app (compojure.handler/site all-routs)) (используйте 'peridot.core) (-> (приложение сеанса) (запрос "/test/json":request-method:post:body (java.io.ByteArrayInputStream. (.getBytes "привет" "UTF-8")))
дает IOException: stream closed
,
Есть лучший способ сделать это?
2 ответа
tldr:
(-> (session app)
(request "/test/json"
:request-method :post
:content-type "application/json"
:body (.getBytes "\"hello\"" "UTF-8")))
Когда перидот генерирует карту запроса, по умолчанию application/x-www-form-urlencoded
для типа контента для :post
запрос. С приложением, как указано wrap-params
(который включен compojure.handler/site
) попытаюсь прочитать :body
чтобы проанализировать любые параметры, закодированные в форме. затем json-post
попытки прочитать :body
снова. тем не мение InputStream
s предназначены для чтения один раз, и это вызывает исключение.
Есть два основных способа решения проблемы:
- Удалить
compojure.handler/site
, - Добавить тип контента в запрос (как это сделано в tldr)
(require '[cheshire.core :as json])
(-> (session app)
(request "/test/json"
:request-method :post
:content-type "application/json"
:body (json/generate-string data))
Не нужно звонить .getBytes
Просто передайте JSON с :body
параметр.