如何使用Pedestal编写简易拦截器提取GET/POST请求中的JSON?及EDN请求体回声API异常排查
2. EDN请求回声功能排查与修复
看了你的代码,我发现几个关键问题,咱们一步步修复:
问题1:get-in语法错误
你写的(get-in context [:request] :edn-params)是错误的——get-in的第二个参数必须是完整的路径向量,正确写法应该是(get-in context [:request :edn-params])。
问题2:GET请求不支持请求体
你的路由用的是:get方法,但GET请求默认不会携带请求体,body-params拦截器自然也不会解析任何体内容。要传EDN/JSON体,得把路由改成:post或者:put。
问题3:Content-Type匹配与参数键对应
body-params会根据请求的Content-Type头把解析后的数据放到不同的键里:
application/edn→:edn-paramsapplication/json→:json-paramsapplication/x-www-form-urlencoded→:form-params
你需要根据请求的Content-Type来选择对应的参数键,不然可能拿到nil。
修复后的完整代码
路由修改为POST
(def routes (route/expand-routes #{["/echo" :post [body-params/body-params print-response] :route-name :echo]}))
修复后的print-response拦截器
(def print-response {:name ::print-response :leave (fn [context] (let [request (:request context) content-type (get-in request [:headers "content-type"] "text/plain") ;; 根据Content-Type选择要返回的参数 response-body (condp re-find content-type #"application/edn" (:edn-params request) #"application/json" (:json-params request) ;; 处理不支持的Content-Type {:error "Unsupported Content-Type. Use application/edn or application/json"})] ;; 用update简化response的修改 (update context :response assoc :status 200 :headers {"Content-Type" content-type} :body response-body)))})
测试方法
用curl测试EDN请求:
curl -X POST -H "Content-Type: application/edn" -d "{:name \"Alice\" :age 30}" http://localhost:8080/echo
测试JSON请求:
curl -X POST -H "Content-Type: application/json" -d '{"name": "Bob", "age": 25}' http://localhost:8080/echo
如果一定要用GET请求传数据,那得把EDN/JSON放到查询参数里,比如/echo?data={:name "Alice"},这时候需要自己解析:query-params里的data字段,而不是依赖body-params。
内容的提问来源于stack exchange,提问作者Pouriyatajmehrabi
相关产品推荐
相关产品推荐

