我如何模仿环中的json帖子请求?

时间:2013-06-11 01:40:50

标签: clojure ring

我正在使用橄榄石 - https://github.com/xeqi/peridot来测试我的铃声应用程序,并且它正常工作,直到我尝试使用json数据模拟一个post请求:

(require '[cheshire.core :as json])
(use 'compojure.core)

(defn json-post [req]
  (if (:body req)
    (json/parse-string (slurp (:body req)))))

(defroutes all-routes
  (POST "/test/json" req  (json-response (json-post req))))

(def app (compojure.handler/site all-routes))

(use 'peridot.core)

(-> (session app)
    (request "/test/json"
             :request-method :post
             :body (java.io.ByteArrayInputStream. (.getBytes "hello" "UTF-8")))

给出IOException: stream closed

有更好的方法吗?

2 个答案:

答案 0 :(得分:9)

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以解析任何form-urlencoded参数。然后json-post尝试再次阅读:body。但是InputStream被设计为只读一次,这会导致异常。

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

  1. 删除compojure.handler/site
  2. 向请求添加内容类型(如在tldr中所做的那样)

答案 1 :(得分:4)

(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。