我认为我做得对,但我无法从:body输入流中获取EDN。环法和组合处理程序是这样的:
依赖关系:
[ring.middleware.params :as params]
[ring.middleware.edn :as edn]; https://github.com/tailrecursion/ring-edn处理程序:
(defroutes ajax-example
(PUT "/ajax-example" r
(println r)
{:status 200
:headers {"Content-Type" "application/edn"}
:body "yo"}))我把它包装成:
(def ajax-wrapped
(-> ajax-example
edn/wrap-edn-params
params/wrap-params))printlnd响应正确地揭示了它是EDN,并且基于我发送的简单测试地图,内容长度是正确的,但是地图本身无处可寻,它永远被困在:body的输入流中.如何得到它?
以下是响应println:
{:ssl-client-cert nil,:remote-addr 0:0:0:0:0:0:0:1,params {},路由-params {},:headers { http://localhost:6542,主机本地主机:6542,用户代理Mozilla/5.0 (Macintosh;Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML,类似Gecko) Chrome/42.0.2311.135 Safari/537.36,内容类型应用程序/edn,_ga=GA1.1.1354518981.1429622648;内容长度20,引用http://localhost:6542/,连接保持活跃,接受/,接受语言en-US,en;q=0.8,sq;q=0.6,接受编码gzip,缩小,sdch,缓存控制max-age=0},:server-port 6542,内容长度20,:form-params {},:query-params {},:content-type application/edn,:字符编码nil,:uri /ajax-例如:server-name localhost,:query-string nil,:body # :edn-params nil,:put :http :request-method :put}
主体没有正确粘贴在上面,如下所示:
[open corner bracket] HttpInput org.eclipse.jetty.server.HttpInput@5d969109 [end corner bracket]使用cljs-ajax库从浏览器发送的客户端代码是:
(defn ajax-send
[]
(let [push {:adder1 2 :add2 3}]
(PUT "/ajax-example"
{:format :edn
:params push
:handler ajax-result
:error-handler error-handler})))下面是其中一个答案所建议的测试的输出:
hf.examples> ((-> ajax-example params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
(mock/content-type "application/edn")
(mock/body "{:hello \"there\"}")))
{:status 200,
:headers {"Content-Type" "application/edn"},
:body
"{:remote-addr \"localhost\", :params {:hello \"there\"}, :route-params {}, :headers {\"content-length\" \"16\", \"content-type\" \"application/edn\", \"host\" \"localhost\"}, :server-port 80, :content-length 16, :form-params {}, :query-params {}, :content-type \"application/edn\", :uri \"/ajax-example\", :server-name \"localhost\", :query-string nil, :edn-params {:hello \"there\"}, :scheme :http, :request-method :put}"}
hf.examples> 我也试过这个:
(defroutes ajax-example
(PUT "/ajax-example" r
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str (dissoc r :body))}))与前端无关的卷曲结果:
curl -X PUT -H "Content-Type: application/edn" -d '{:name :barnabas}' http://localhost:6542/ajax-example
{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, :headers {"host" "localhost:6542", "content-length" "17", "content-type" "application/edn", "user-agent" "curl/7.37.1", "accept" "*/*"}, :server-port 6542, :content-length 17, :content-type "application/edn", :character-encoding nil, :uri "/ajax-example", :server-name "localhost", :query-string nil, :edn-params nil, :scheme :http, :request-method17的content-length与通过Curl传递的映射中的字符数相匹配。但是edn-params是零的!内容在哪里?
发布于 2015-05-13 13:34:11
编辑:作为对更新问题的回答,wrap params函数通过完全读取:body InputStream来消耗请求的主体。Compojure路由将请求传递给每个参数处理程序,直到返回一个非零值为止。在这种情况下,无论哪种处理程序被传递给路由,第一个处理程序将消耗:body,而第二个处理程序将不存在:body值,从而导致由wrap edn-params读取的零正文值。
传递给环处理程序的请求可能没有将其内容类型设置为edn。只有当请求内容类型设置为edn时,环绕-edn-仿射函数才会解析edn。
此外,解析的edn参数将只被放在请求映射的:params和: edn -params键中,因此:body不应该用于访问解析的edn。
(require '[ring.mock.request :as mock])
(require '[ring.middleware.edn :as edn])
((-> ajax-example params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
(mock/content-type "application/edn")
(mock/body "{:hello \"there\"}")))
{:remote-addr "localhost",
:params {:hello "there"},
:route-params {},
:headers
{"content-length" "16",
"content-type" "application/edn",
"host" "localhost"},
:server-port 80,
:content-length 16,
:form-params {},
:query-params {},
:content-type "application/edn",
:uri "/ajax-example",
:server-name "localhost",
:query-string nil,
:body #<ByteArrayInputStream java.io.ByteArrayInputStream@171788d8>,
:edn-params {:hello "there"},
:scheme :http,
:request-method :put}发布于 2015-05-13 18:07:39
我已经解决了这个问题,但我不知道为什么存在这个问题。我有另外一个独立的路线,也包裹EDN中间件。下面是一个可重复的例子:
(defroutes example-routes2
(PUT "/test-edn" r
(println r)
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str (str "request is: " r))}))
(defroutes ajax-example
(PUT "/ajax-example" r
(println r)
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str (str "request is: " r))}))
(def edn-routes
(-> example-routes2
edn/wrap-edn-params))
(def ajax-wrapped
(-> ajax-example
edn/wrap-edn-params))
;;combining all routes on this page into a single handler
(def example-routes (routes example-routes1 ajax-wrapped edn-routes))请注意,这两条路由本质上是相同的,并且包装是相同的。没有将EDN解析为edn-params的example-routes 是 def!中的第二位。
curl -X -H“-H-Type: application/edn”-d '{:name :barnabasss}‘http://localhost:6542/test-edn
返回:
“请求是:{:ssl-client-cert nil,:remote-addr \”0:0:0:0:0:0:0:0:0:1“”,:params {},路由-params {},:headers {\"host\“\"localhost:6542\",\"content-length\”\"19\",\“content-type\ \"application/edn\",\"user-agent\”\"curl/7.37.1\",\"/\"},:server-端口6542,:内容长度19,内容-类型\"application/edn\",:字符编码nil,:uri \"/test-edn\",:server-name \"localhost\",:query-string nil,:body #,:edn-params nil,: :http :http:请求-方法:put}“
curl -X -H“-H-Type: application/edn”-d '{:name :barnabasss}‘http://localhost:6542/ajax-example
返回:
“请求是:{:ssl-client-cert nil,:remote-addr \”0:0:0:0:0:0:0:0:0:0:0:0:0:1\“,:params {:name :barnabasss},:name params {},:headers {\"host\”\"localhost:6542\",\“内容-长度\"19\",\”内容-类型\\“应用程序/edn\”,\"user-agent\“\"curl/7.37.1\",\“接受\\”/\},:server-端口6542,内容长度19,内容类型\"application/edn\",:字符编码nil,:uri \“/ajax-示例”,:server-name \"localhost\",:query-string nil,:body #,:edn-params {:name :barnabasss},:put :http :请求-方法:put}“
在example-routes交换机中切换它们的顺序,其中一个是工作的。有人能解释吗?
https://stackoverflow.com/questions/30209769
复制相似问题