【问题标题】:How to send an input stream as a response in ring?如何在环中发送输入流作为响应?
【发布时间】:2020-06-20 05:42:26
【问题描述】:

我有以下代码,我想在函数fetch-items 中发送文件的InputStream,该函数处理路由/fetch-items。

(defn id->image [image-id]
    (let [image (.getInputStream (gfs/find-by-id fs image-id))] image))

(defn item-resp [item]
  (assoc item :_id (str (:_id item))
         :images (into [] (map id->image (:image-ids item))))
  )

(defn fetch-items [req]
  (res/response 
   (map item-resp (find fs "items" {}))))

这是我在客户端的请求,使用cljs-ajax

   (ajax-request
    {:uri "http://localhost:5000/fetch-items"
     :method :get
     :handler #(prn (into [] %))
     :format (json-request-format)
     :response-format (raw-response-format)
     }
    )

但是我在客户端得到的响应是这样的:

[:failure :parse] [:response nil] [:status-text "No reader function for tag object.  Format should have been EDN"]
:original-text "{:_id \"5e63f5c591585c30985793cd\", :images [#object[com.mongodb.gridfs.GridFSDBFile$GridFSInputStream 0x22556652 \"com.mongodb.gridfs.GridFSDBFile$GridFSInputStream@22556652\"]]}{:_id \"5e63f5d891585c30985793d0\", :images [#object[com.mongodb.gridfs.GridFSDBFile$GridFSInputStream 0x266ae6c0 \"com.mongodb.gridfs.GridFSDBFile$GridFSInputStream@266ae6c0\"]]}{:_id \"5e63f5e891585c30985793d3\", ...

为什么响应会说格式应该是 edn?如何在客户端提取此文件/图像?

--- 编辑 ----

执行以下操作:

(IOUtils/toString image "utf-8")

返回一个大小为 1594 字节的字符串,它比预期的图像大小要小得多。 我认为这是因为它将文件对象转换为 base64,而不是与其关联的实际数据块。

如何使它将实际的 GridFS 块转换为 base64 字符串而不是文件对象?

【问题讨论】:

    标签: clojure inputstream clojurescript gridfs monger


    【解决方案1】:

    您似乎正在构建响应并将对 InputStream 对象的引用直接放入响应中,而没有将流的内容编码为字节数组并将响应中的内容序列化。

    您需要找到一种方法来读取流的内容并在响应中对其进行编码(也许将它们编码为 base 64?)

    另一方面,客户端似乎期待 EDN 响应,当它找到字符串 #object 时,它抱怨它没有办法读取带有这样标签的对象。

    这是一个简单示例,说明如何读取带有标记文字的 EDN 字符串,您可以对其进行扩展,以便在客户端中解码图像(注意我在解码器中使用 Java,您需要在JS):

    (defn b64decode [s]
      (->> s .getBytes (.decode (java.util.Base64/getDecoder)) String.))
    
    (def message "{:hello :world :msg #base64str \"SGV5LCBpdCB3b3JrcyE=\"}")
    
    ;; Now we can read the EDN string above adding our handler for #base64str
    
    (clojure.edn/read-string {:readers {'base64str b64decode}} message)
    ;; => {:hello :world, :msg "Hey, it works!"}
    
    
    

    【讨论】:

    • 有什么快速将InputStream转换成base64字符串的方法?
    • 链接代码或 (IOUtils/toString my-input-stream "utf-8") 似乎都不适用于 GridFSDBInputStream,因为在这两种情况下我为每个文件都得到了相同的 base64 字符串,并且是也不足以成为图像。
    • 在您的代码示例中,函数id->image 似乎不完整。检查你是否真的把InputStream的内容改成了slurp,用count判断它是否和你期望的一样大
    • 似乎所有这些方法都将文件对象转换为base64,而不是与文件对象关联的实际gridfs块。查看编辑了解详情。
    猜你喜欢
    • 2023-03-15
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 2019-01-06
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多