我认为我做得对,但我无法从:body
输入流中获取我的EDN。 Ring和Compojure处理程序是这样的:
依赖关系:
[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))
println
'd响应正确显示它是EDN,内容长度是正确的,基于我发送的简单测试图,但地图本身无处可寻,它永远被困在:body
的输入流...如何获得它?
以下是响应println:
{:ssl-client-cert nil,:remote-addr 0:0:0:0:0:0:0:1,:params {} ,: route-params {} ,: headers {origin {{ 3}},主机localhost: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,cookie _ga = GA1.1.1354518981.1429622648; content-length 20,referer http://localhost:6542,connection keep-alive,accept / ,accept-language en-US,en; q = 0.8,sq; q = 0.6,accept-encoding gzip ,deflate,sdch,cache-control max-age = 0} ,: server-port 6542,:content-length 20,:form-params {} ,: query-params {} ,: content-type application / edn ,: character-encoding nil,:uri / ajax-example,:server-name localhost,:query-string nil,:body#,:edn-params nil,:scheme:http,:request-method:put}
:身体上面没有正确粘贴,看起来像这样:
[open corner bracket] HttpInput org.eclipse.jetty.server.HttpInput@5d969109 [end corner bracket]
使用cljs-ajax
lib从浏览器发送的客户端代码是:
(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-method
17的content-length
匹配通过Curl传递的地图中的字符数。但是edn-params
是零!内容在哪里?
答案 0 :(得分:3)
编辑:作为更新问题的答案,wrap-edn-params函数通过完全读取:body InputStream来消耗请求的主体。 Compojure路由将请求传递给每个参数处理程序,直到返回非nil值。在这种情况下,无论哪个处理程序传递给路由,因为第一个处理程序将使用:body,并且第二个处理程序将不会使用:body值,导致wrap-edn-params读取nil正文值。
传递给环处理程序的请求可能没有将其content-type设置为edn。如果请求内容类型设置为edn,wrap-edn-params function将仅解析edn。
此外,解析的edn参数将仅通过wrap-edn-params函数放置在请求映射的: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}
答案 1 :(得分:0)
我已修复此问题,但我不知道问题存在的原因。我有另一条独立的路线,也包裹着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中列出的第二个
卷曲-X PUT -H&#34;内容类型:application / edn&#34; -d&#39; {:name:barnabasss}&#39; http://localhost:6542/test-edn
返回:
&#34;请求是:{:ssl-client-cert nil,:remote-addr \&#34; 0:0:0:0:0:0:0:1 \&#34;,: params {},:route-params {} ,: headers {\&#34; host \&#34; \&#34; localhost:6542 \&#34;,\&#34; content-length \&#34; \&#34; 19 \&#34;,\&#34;内容类型\&#34; \&#34; application / edn \&#34;,\&#34; user-agent \&#34; \&#34; curl / 7.37.1 \&#34;,\&#34;接受\&#34; \&#34; / \&#34;} ,: server-port 6542,:content-length 19,:content-type \&#34; application / edn \&#34;, :字符编码nil,:uri \&#34; / test-edn \&#34;,:server-name \&#34; localhost \&#34; ,: query-string nil,:body#,< strong>:edn-params nil,:scheme:http,:request-method:put}&#34;
卷曲-X PUT -H&#34;内容类型:application / edn&#34; -d&#39; {:name:barnabasss}&#39; http://localhost:6542/ajax-example
返回:
&#34;请求是:{:ssl-client-cert nil,:remote-addr \&#34; 0:0:0:0:0:0:0:1 \&#34;,: params {:name:barnabasss} ,: route-params {} ,: headers {\&#34; host \&#34; \&#34; localhost:6542 \&#34;,\&#34; content-length \&#34; \&#34; 19 \&#34;,\&#34;内容类型\&#34; \&#34; application / edn \&#34;,\&#34; user-agent \&#34; \&#34; curl / 7.37.1 \&#34;,\&#34;接受\&#34; \&#34; / \&#34;} ,: server-port 6542,:content-length 19,:content-type \&#34; application / edn \&#34;, :字符编码nil,:uri \&#34; / ajax-example \&#34;,:server-name \&#34; localhost \&#34; ,: query-string nil,:body#,< strong>:edn-params {:name:barnabasss},:scheme:http,:request-method:put}&#34;
在example-routes
开关中切换它们的顺序。谁能解释一下?