Как отправить входной поток в ответ на звонок? - PullRequest
0 голосов
/ 07 марта 2020

У меня есть следующий код, в котором я хочу отправить 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" {}))))

Вот мой запрос в на стороне клиента, используя cl js - 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? Как извлечь этот файл / изображение на стороне клиента?

--- EDIT ----

Выполнение следующих действий:

(IOUtils/toString image "utf-8")

возвращает строку размером 1594 байта, что намного меньше ожидаемого размера изображения. Я думаю, что это потому, что он преобразует объект файла в base64, а не фактический кусок данных, связанных с ним. database instance

Как мне сделать так, чтобы преобразовать фактический кусок GridFS в строку base64, а не в объект файла?

1 Ответ

1 голос
/ 07 марта 2020

Похоже, что вы создаете ответ и непосредственно помещаете ссылку на объект 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!"}


...