将HTTP请求主体作为字符串读取

9
处理ring服务器中的http请求时,请求数据的主体存储在请求哈希映射中的键:body中。例如,如下所示:
#object[org.eclipse.jetty.server.HttpInputOverHTTP 0x2d88a9aa "HttpInputOverHTTP@2d88a9aa"] 

如果我只对原始文本感兴趣,那么我该如何读取此对象?
3个回答

13
您可以使用ring.util.request/body-string来将请求体作为字符串获取。
(body-string request) 

您需要记住InputStream只能读取一次,因此您可能更喜欢用已读String替换原始:body,以便稍后可以再次访问它:

(defn wrap-body-string [handler]
  (fn [request]
    (let [body-str (ring.util.request/body-string request)]
      (handler (assoc request :body (java.io.StringReader. body-str))))))

并添加您的中间件来包装处理程序:

(def app
  (wrap-body-string handler))

这很好,但它在某种程度上破坏了ring.middleware.params中的wrap-params - undefined

4

正如user1338062所建议的那样,您可以简单地在请求体上调用slurp

(defn handler [request]
  (let [body (slurp (:body request))]))

请不要仅仅发布代码作为答案,还要提供解释您的代码是如何解决问题的。带有解释的答案通常更有帮助和更高质量,并且更有可能吸引赞同。 - Mark Rotteveel
@MarkRotteveel 您是正确的。我更新了我的回复 :) - kazuwal

0

Ring请求的:body必须是java.io.InputStream的实例。 因此,您可以使用reader + slurp将其转换为字符串。

(defn is->str [is]
  (let [rdr (clojure.java.io/reader is)]
    (slurp rdr)))

使用方法:(is->str (:body request))


"slurp" 可以直接消耗 InputStream,不需要将其包装在读取器中。 - user1338062

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接