0

我有以下代码,我想在函数中发送文件的 InputStream,该函数fetch-items处理路由 /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 字符串而不是文件对象?

4

1 回答 1

1

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

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

另一方面,客户端似乎期待 EDN 响应,当它找到 string 时#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!"}


于 2020-03-07T20:46:02.853 回答