【问题标题】:compojure wrap-json-body not workingcompojure wrap-json-body 不起作用
【发布时间】:2014-04-21 14:07:32
【问题描述】:

我正在使用下面的代码尝试访问 PUT 请求中的一些 json 输入,但是我返回的是 :body {},我不确定我做错了什么?

(ns compliant-rest.handler
  (:use compojure.core ring.middleware.json)
  (:require [compojure.handler :as handler]
            [compojure.route :as route]
            [ring.util.response :refer [response]]
            [clojure.data.json :refer [json-str]]))

(defroutes app-routes
  (PUT "/searches" {body :params} (response body))
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (-> (handler/site app-routes)
      (wrap-json-body)
      (wrap-json-response)))

(app {
      :request-method :put 
      :uri "/searches" 
      :content-type "application/json" 
      :body (with-in-str (json-str {:field "value"}))
      })

;; {:status 200, :headers {"Content-Type" "application/json; charset=utf-8"}, :body "{}"}

另外,我是 Clojure/Lisp 的新手,任何关于我的语法和风格的 cmets 都将不胜感激。

【问题讨论】:

    标签: clojure compojure ring


    【解决方案1】:

    感谢 Joost 和 cmets,我发现有一个环函数 ring.util.io.string-input-stream 可以完成我错误地认为 with-in-str 所做的事情。最后我做了以下工作:

    (ns compliant-rest.handler
      (:use compojure.core ring.middleware.json)
      (:require [compojure.handler :as handler]
                [compojure.route :as route]
                [ring.util.response :refer [response]]
                [ring.util.io :refer [string-input-stream]]
                [clojure.data.json :refer [json-str]]))
    
    (defroutes app-routes
      (PUT "/searches/:id" {params :params body :body}
           (response body))
      (route/resources "/")
      (route/not-found "Not Found"))
    
    (def app
      (-> (handler/site app-routes)
          (wrap-json-body)
          (wrap-json-response)))
    
    ;; Example request
    (app {
          :request-method :put 
          :uri "/searches/1" 
          :content-type "application/json" 
          :body (string-input-stream (json-str {:key1 "val1"}))
          })
    ;; {:status 200, :headers {"Content-Type" "application/json; charset=utf-8"}, :body "{\"key1\":\"val1\"}"}
    

    太棒了,我可以创建一个简单的地图并调用我的 api 的入口点,而无需任何类型的服务器或模拟。使用 Clojure、repl 和 light 表,我完全被这整个动态语言所吸引!

    【讨论】:

      【解决方案2】:

      有两点很突出:

      未解析的请求正文不应是字符串,而是 InputStream。这意味着您的测试表达式不会按原样工作。

      wrap-json-body 将 (:body request) 替换为 clojure 数据结构。它不会在 (:params request) 或 (:body (:params request)) 中放入任何内容。你想要 wrap-json-params 。

      【讨论】:

      • with-in-str 是从字符串创建输入流。那么我该如何解构以从路由中访问 body 数据结构呢?
      • with-in-str 创建一个输入流,但将其绑定到*in*。这可能有效,但我建议您在 ring.mock.request 库中使用 requestbody 函数。
      • 您可以使用 (PUT "/searches" {body :body} ...) 来获取请求中的 :body 值。
      猜你喜欢
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2017-01-11
      • 2016-05-23
      • 1970-01-01
      • 2015-11-26
      相关资源
      最近更新 更多