从 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 的整个定义,应用程序似乎也能正常启动,我假设是因为服务器是用 handlerserver.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.cljserver.clj 中不同处理程序的推理,请随时告诉我。