编辑 - source code is on github如果您有兴趣的话。感谢
我对如何访问已发布到clojure中的url的json数据感到有点困惑;我似乎无法让它发挥作用。
这是我的路线:
(cc/POST "/add"
request
(str ": " request))
我不完全确定我必须代替request
- 我只是在网上看到了一些博客,并试图遵循它,但无法让它发挥作用。
以下是我试图发布的内容:(来自fiddler)
注意:请求标头端口在图像中是不同的;这是一个错误,我试图弄乱这些数据,看看它是什么,所以请忽略上面图片中的那一部分
在卷曲中,我只是这样做:
curl -X POST -H "Content-Type: application/json" -d '{"foo":"bar","baz":5}'
http://localhost:3005/add
看起来clojure没有收到我发布的json数据。
以下是请求var包含的内容:
: {:scheme :http, :query-params {}, :form-params {}, :request-method :post,
:query-string nil, :route-params {}, :content-type "\"application/json\"",
:uri "/event", :server-name "localhost", :params {},
:headers {"user-agent" "Fiddler", "content-type" "\"application/json\"",
"content-length" "23", "host" "localhost:3005"},
:content-length 23, :server-port 3005, :character-encoding nil, :body #}
如您所见,所有params
都是空的......
我正在使用compojure和cheshire - 我可以将数据转换为json并将它们返回到GET
路由就好了。我需要弄清楚如何传递json并将其转换为clojure数据..
感谢
答案 0 :(得分:7)
那是因为:params由一个处理“表单编码”主体的环中间件填充。
您可以使用ring-json将应用程序包装到其他中间件中。它将解析JSON主体并相应地填充:params。 (https://github.com/ring-clojure/ring-json)
答案 1 :(得分:1)
这是一个做你想要的例子。代码来自此project。在README中,您将看到它支持的一些访问模式。代码有点乱,但它应该说明如何做到这一点。
(ns poky.protocol.http.jdbc.text
(:require [poky.kv.core :as kv]
(compojure [core :refer :all]
[route :as route]
[handler :as handler])
[ring.util.response :refer [response not-found]]
(ring.middleware [format-response :as format-response ]
[format-params :as format-params])
[cheshire.core :as json]
[ring.middleware.stacktrace :as trace]))
;
; curl -d"some data" -H'Content-Type: application/text' -v -X PUT http://localhost:8080/xxx
; curl -d'{"bla":"bar"}' -H'Content-Type: application/json' -v -X PUT http://localhost:8080/bla
(def valid-key-regex #"[\d\w-_.,]+")
; FIXME: this should be split- one fn for get, one for mget
(defn- wrap-get
[kvstore ks params headers body]
(response
(let [eks (clojure.string/split ks #",")
nks (count eks)
multi (> nks 1)
ret (if multi (kv/mget* kvstore eks) (kv/get* kvstore ks))]
(condp = (get headers "accept")
"application/json" ret
"text/plain" (if multi (throw (Exception. "Multi get unsupported with Accept: text/plain")) (get ret ks))
ret))))
(defn- wrap-put
[kvstore ks params headers body]
(if (and
(= (get headers "content-type") "application/json")
(get params (keyword ks) nil))
(kv/set* kvstore ks (get params (keyword ks)))
(kv/set* kvstore ks body))
(response ""))
(defn api
[kvstore]
(let [api-routes
(routes
(GET ["/:ks" :ks valid-key-regex] {{:keys [ks] :as params} :params body :body headers :headers}
(wrap-get kvstore ks params headers body))
(PUT ["/:ks" :ks valid-key-regex] {{:keys [ks] :as params} :params
body :body body-params :body-params headers :headers}
(let [body (slurp body)
body (if (empty? body) body-params body)]
(wrap-put kvstore ks params headers body))))]
(-> (handler/api api-routes)
(format-params/wrap-format-params
:predicate format-params/json-request?
:decoder #(json/parse-string % true)
:charset format-params/get-or-guess-charset)
(format-response/wrap-format-response
:predicate format-response/serializable?
:encoders [(format-response/make-encoder json/encode "application/json")
(format-response/make-encoder identity "text/plain")]
:charset "utf-8")
trace/wrap-stacktrace)))
希望这有帮助。
答案 2 :(得分:0)
只需更新以前的答案,现在就足以添加get
键,其中包含将由Ring处理到您的处理程序的格式列表。
类似
formats