首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在此服务器请求中解析出EDN。

无法在此服务器请求中解析出EDN。
EN

Stack Overflow用户
提问于 2015-05-13 08:40:38
回答 2查看 1.2K关注 0票数 3

我认为我做得对,但我无法从:body输入流中获取EDN。环法和组合处理程序是这样的:

依赖关系:

代码语言:javascript
复制
 [ring.middleware.params :as params]
 [ring.middleware.edn :as edn]; https://github.com/tailrecursion/ring-edn

处理程序:

代码语言:javascript
复制
(defroutes ajax-example
  (PUT "/ajax-example" r
       (println r)
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body "yo"}))

我把它包装成:

代码语言:javascript
复制
  (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}

主体没有正确粘贴在上面,如下所示:

代码语言:javascript
复制
 [open corner bracket] HttpInput org.eclipse.jetty.server.HttpInput@5d969109 [end corner bracket]

使用cljs-ajax库从浏览器发送的客户端代码是:

代码语言:javascript
复制
(defn ajax-send
  []
  (let [push {:adder1 2 :add2 3}]
    (PUT "/ajax-example" 
         {:format :edn 
          :params push
          :handler ajax-result
          :error-handler error-handler})))

下面是其中一个答案所建议的测试的输出:

代码语言:javascript
复制
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> 

我也试过这个:

代码语言:javascript
复制
(defroutes ajax-example
  (PUT "/ajax-example" r
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body (pr-str (dissoc r :body))}))

与前端无关的卷曲结果:

代码语言:javascript
复制
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是零的!内容在哪里?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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。

代码语言:javascript
复制
(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}
票数 3
EN

Stack Overflow用户

发布于 2015-05-13 18:07:39

我已经解决了这个问题,但我不知道为什么存在这个问题。我有另外一个独立的路线,也包裹EDN中间件。下面是一个可重复的例子:

代码语言:javascript
复制
(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交换机中切换它们的顺序,其中一个是工作的。有人能解释吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30209769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档