2013-06-11 11 views
8

Sto utilizzando peridoto - https://github.com/xeqi/peridot per testare la mia applicazione ad anello, e il suo bel lavoro fino a quando cerco di prendere in giro una richiesta POST con i dati JSON:come faccio a prendere in giro una richiesta json post in anello?

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

C'è un modo migliore per farlo?

risposta

9

TLDR:

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

Quando peridoto genera una mappa richiesta imposterà application/x-www-form-urlencoded per il tipo di contenuto per una richiesta :post. Con l'app come specificato wrap-params (che è incluso da compojure.handler/site) tenterà di leggere lo :body per analizzare qualsiasi parametro urlencoded del modulo. Quindi json-post tenta di leggere di nuovo il :body. Tuttavia, gli InputStream s sono progettati per essere letti una sola volta e ciò causa l'eccezione.

ci sono fondamentalmente due modi per risolvere il problema:

  1. Rimuovere compojure.handler/site.
  2. Aggiungi un tipo di contenuto alla richiesta (come fatto in TLDR)
4
(require '[cheshire.core :as json]) 

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

Non c'è bisogno di chiamare .getBytes, basta passare JSON con :body parametro.

Problemi correlati