Compojure 未获取请求正文

mun*_*unk 2 clojure compojure

我有一个使用 Compojure 和此类端点的应用程序

(defroutes routes
  (POST "/api/v1/echo" req (str req))

(def http-handler
  (reload/wrap-reload (wrap-defaults #'routes api-defaults)))

(defn run-web-server []
    (run-jetty http-handler {:port 10555 :join? false}))
Run Code Online (Sandbox Code Playgroud)

当我尝试这个卷曲请求时

curl -X POST -H "Content-Type: application/json" http://localhost:10555/api/v1/echo -d '{"hello": "world"}'
Run Code Online (Sandbox Code Playgroud)

我得到这个回应

{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, :headers {"accept" "*/*", "user-agent" "curl/7.43.0", "content-type" "application/json", "content-length" "18", "host" "localhost:10555"}, :server-port 10555, :content-length 18, :form-params {}, :query-params {}, :content-type "application/json", :character-encoding nil, :uri "/api/v1/echo", :server-name "localhost", :query-string nil, :body #object[org.eclipse.jetty.server.HttpInput 0x4317e5fa "org.eclipse.jetty.server.HttpInput@4317e5fa"], :scheme :http, :request-method :post}%
Run Code Online (Sandbox Code Playgroud)

我期望看到的是该响应中的{"hello", "world"} 某处,但它不在那里。我看到有:body HttpInput,但是当我尝试(prn (-> req :body .read))它时,它会输出123。因为(= "{\"hello\", \"world\"}" 123) => false,我有点不知道接下来要尝试什么。

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" http://localhost:10555/api/v1/echo -d "foo=1&bar=2"确实按预期工作并返回:params {:foo "1", :bar "2"},但我宁愿提交 json. 我知道我可能可以使用 compojure-api,但我很好奇为什么会这样。

Die*_*sch 6

您需要使用ring-json中间件,特别wrap-json-body是解析json参数:

wrap-json-body 中间件会将任何具有 JSON 内容类型的请求正文解析为 Clojure 数据结构,并将其分配给 :body 键。

这是处理 JSON 请求的首选方式。