You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:02:19