从 HTTP 请求中解析 JSON 正文(使用 ring 和 re-frame-http-fx)
Parse JSON body from HTTP request (with ring and re-frame-http-fx)
我有一个基于重新帧的 UI 并尝试使用 re-frame-http-fx 与我的服务器通信。发送和回复似乎有效。但是,我无法弄清楚如何将 JSON 正文解析为服务器上的 Clojure 映射。
这是我的 handler.clj
尽可能少的:
(ns my.handler
(:require [compojure.core :refer [GET POST defroutes]]
[compojure.route :refer [resources]]
[ring.util.response :refer [resource-response]]
[ring.middleware.json :refer [wrap-json-response wrap-json-body]]))
(defn json-post [request]
(let [body (:body request)]
(prn body)
body))
(defroutes routes
(GET "/" [] (resource-response "index.html" {:root "public"}))
(POST "/post" request json-post)
(resources "/"))
(def handler (wrap-json-response (wrap-json-body routes {:keywords? true})))
据我了解,wrap-json-body
中间件应该用解析后的版本(地图?)替换请求主体。
但是,我在 json-post
处理程序中从 (prn body)
得到的输出是这样的:
#object[org.httpkit.BytesInputStream 0xda8b162 "BytesInputStream[len=41]"]
如果我尝试 (prn (:title body))
之类的东西,我会得到 nil
(尽管原始地图转换的-json-请求包含 :title
,以及两个请求和响应正文)。
请求和响应包含正确的 json。请求 Content-Type
已正确设置为 application/json
(由 re-frame-http-fx
发送)。缓冲区的长度 (41) 也是根据请求的正确主体长度。
我 运行 没法尝试了。有什么想法吗?
在进一步调查这个问题时,我发现了我的错误导致了这个结果。它涉及 re-frame 模板中的 dev-handler
,我从问题中的最小示例中方便地省略了它。
我没有意识到这是一个问题,因为即使您从 handler.clj
中删除 dev-handler
的整个定义,应用程序似乎也能正常启动,我假设是因为服务器是用 handler
在 server.clj
中(并且客户端不会致命失败)。
然而,在re-frame模板的project.clj
中,figwheel配置如下:
:figwheel {:css-dirs ["resources/public/css"]
:ring-handler my.handler/dev-handler}
这导致为 handler
配置的中间件未应用于我的请求,因此未展开 json 主体。更改 dev-handler
的定义(与问题中的 handler
相同)或 project.clj
中 figwheel 的配置(指向 handler
而不是 dev-handler
) 解决问题。
如果有人知道 project.clj
和 server.clj
中不同处理程序的推理,请随时告诉我。
我有一个基于重新帧的 UI 并尝试使用 re-frame-http-fx 与我的服务器通信。发送和回复似乎有效。但是,我无法弄清楚如何将 JSON 正文解析为服务器上的 Clojure 映射。
这是我的 handler.clj
尽可能少的:
(ns my.handler
(:require [compojure.core :refer [GET POST defroutes]]
[compojure.route :refer [resources]]
[ring.util.response :refer [resource-response]]
[ring.middleware.json :refer [wrap-json-response wrap-json-body]]))
(defn json-post [request]
(let [body (:body request)]
(prn body)
body))
(defroutes routes
(GET "/" [] (resource-response "index.html" {:root "public"}))
(POST "/post" request json-post)
(resources "/"))
(def handler (wrap-json-response (wrap-json-body routes {:keywords? true})))
据我了解,wrap-json-body
中间件应该用解析后的版本(地图?)替换请求主体。
但是,我在 json-post
处理程序中从 (prn body)
得到的输出是这样的:
#object[org.httpkit.BytesInputStream 0xda8b162 "BytesInputStream[len=41]"]
如果我尝试 (prn (:title body))
之类的东西,我会得到 nil
(尽管原始地图转换的-json-请求包含 :title
,以及两个请求和响应正文)。
请求和响应包含正确的 json。请求 Content-Type
已正确设置为 application/json
(由 re-frame-http-fx
发送)。缓冲区的长度 (41) 也是根据请求的正确主体长度。
我 运行 没法尝试了。有什么想法吗?
在进一步调查这个问题时,我发现了我的错误导致了这个结果。它涉及 re-frame 模板中的 dev-handler
,我从问题中的最小示例中方便地省略了它。
我没有意识到这是一个问题,因为即使您从 handler.clj
中删除 dev-handler
的整个定义,应用程序似乎也能正常启动,我假设是因为服务器是用 handler
在 server.clj
中(并且客户端不会致命失败)。
然而,在re-frame模板的project.clj
中,figwheel配置如下:
:figwheel {:css-dirs ["resources/public/css"]
:ring-handler my.handler/dev-handler}
这导致为 handler
配置的中间件未应用于我的请求,因此未展开 json 主体。更改 dev-handler
的定义(与问题中的 handler
相同)或 project.clj
中 figwheel 的配置(指向 handler
而不是 dev-handler
) 解决问题。
如果有人知道 project.clj
和 server.clj
中不同处理程序的推理,请随时告诉我。