Ring和Compojure中application/json类型POST请求无法获取参数的解决方法咨询
解决Compojure/Ring无法解析JSON POST请求参数的问题
你的curl命令是正确的,问题出在服务端的Ring中间件配置上——默认情况下,ring-defaults并不会自动解析JSON格式的请求体,需要额外添加ring-json中间件来处理JSON数据。下面是具体的解决步骤:
1. 添加必要的依赖
首先在你的project.clj中加入ring-json依赖,版本选择和你的Clojure 1.8兼容的0.4.0:
[org.clojure/clojure "1.8.0"] [compojure "1.5.1"] [ring/ring-defaults "0.2.1"] [ring/ring-json "0.4.0"] ; 新增JSON解析依赖
2. 修改Handler代码,添加JSON解析中间件
更新你的handler.clj,引入ring.middleware.json的中间件,并包装你的路由,让它能解析JSON请求体:
(ns sof.rest.handler (:require [compojure.core :refer :all] [compojure.route :as route] [ring.middleware.json :refer [wrap-json-body wrap-json-response]] [ring.middleware.defaults :refer [wrap-defaults api-defaults]])) (defroutes app-routes ; 从request的:body-params中获取解析后的JSON参数 (POST "/agents" request (str "成功接收参数: " (:body-params request))) (route/not-found "404 Not Found")) (def app (-> app-routes ; 开启JSON解析,将JSON的键转为Clojure关键字 (wrap-json-body {:keywords? true}) ; 可选:如果你的接口需要返回JSON响应,加上这个中间件 wrap-json-response ; 使用api-defaults更适合REST API(比site-defaults精简,不含session/cookie等无关配置) (wrap-defaults api-defaults)))
3. 原理说明
wrap-json-body中间件会自动读取Content-Type: application/json的请求体,将其解析为Clojure的map结构,默认存放在请求的:body-params键下;:keywords? true参数会把JSON中的字符串键(比如"name")转换成Clojure的关键字(比如:name),方便后续处理;- 改用
api-defaults是因为它针对REST API做了优化,去掉了site-defaults中不必要的会话、Cookie等中间件,更符合接口场景。
测试验证
重新启动你的服务,再执行你原来的curl命令:
curl -X POST http://localhost:3000/agents --data '{"name":"verma"}' --header "Content-type:application/json"
你应该会收到类似成功接收参数: {:name "verma"}的响应,说明参数已经被正确解析了。
内容的提问来源于stack exchange,提问作者bpereira
相关产品推荐
相关产品推荐

