9

我正在使用 peridot - 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-routes))

(使用'peridot.core)

(-> (会话应用程序)
    (请求“/test/json”
             :request-method :post
             :body (java.io.ByteArrayInputStream. (.getBytes "hello" "UTF-8")))

IOException: stream closed.

有一个更好的方法吗?

4

2 回答 2

11

tldr:

(-> (session app)
    (request "/test/json"
             :request-method :post
             :content-type "application/json"
             :body (.getBytes "\"hello\"" "UTF-8")))

当 peridot 生成请求映射时,它将默认为请求application/x-www-form-urlencoded的内容类型:post。使用指定的应用程序wrap-params(包含在 中compojure.handler/site)将尝试读取:body以解析任何 form-urlencoded 参数。然后json-post尝试:body再次阅读。但是InputStreams 被设计为读取一次,这会导致异常。

基本上有两种方法可以解决这个问题:

  1. 删除compojure.handler/site.
  2. 向请求添加内容类型(如 tldr 中所做的那样)
于 2013-06-11T03:01:58.827 回答
5
(require '[cheshire.core :as json])

(-> (session app)
    (request "/test/json"
             :request-method :post
             :content-type "application/json"
             :body (json/generate-string data))

无需调用.getBytes,只需传递带:body参数的 json 即可。

于 2015-05-22T06:05:54.013 回答