【发布时间】:2016-05-23 17:57:54
【问题描述】:
在环服务器中处理 http 请求时,请求数据的主体存储在键 :body 的请求哈希图中。比如如下:
#object[org.eclipse.jetty.server.HttpInputOverHTTP 0x2d88a9aa "HttpInputOverHTTP@2d88a9aa"]
如果我只对原始文本感兴趣,我是如何读出这个对象的?
【问题讨论】:
在环服务器中处理 http 请求时,请求数据的主体存储在键 :body 的请求哈希图中。比如如下:
#object[org.eclipse.jetty.server.HttpInputOverHTTP 0x2d88a9aa "HttpInputOverHTTP@2d88a9aa"]
如果我只对原始文本感兴趣,我是如何读出这个对象的?
【问题讨论】:
您可以使用ring.util.request/body-string 将请求正文作为字符串获取。
(body-string request)
您需要记住,InputStream 只能读取一次,因此您可能更愿意将原来的 :body 替换为读取的 String,以便您以后可以再次访问它:
(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))
【讨论】:
按照user1338062 的建议,您只需在请求正文中调用slurp。
(defn handler [request] (let [body (slurp (:body request))]))
【讨论】:
响铃请求的: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,无需将其包装在阅读器中。