我有一个包含图像的数据库,我想通过一些URL提供这些图像,最好是这样:
foobar.com/items?id=whateverTheImageIdIsInTheDatabase.
所以我写了这段代码:
(defn create-item-image []
(let [item-id (:id (:params req))
item
(find-by-id
"items"
(ObjectId. item-id)
)
file-location (str "resources/" item-id ".jpg")
]
(with-open [o (io/output-stream file-location)]
(let [
;; take the first image. The "image" function simply returns the data-url from the id of the image stored in (first (:images item))
img-string (get (str/split (image (first (:images item))) #",") 1)
img-bytes
(.decode (java.util.Base64/getDecoder) img-string)
]
;; write to a file with the name whateverTheImageIdIsInTheDatabase.jpg
(.write o img-bytes)
(.close o)
)
)
)
)
(defn image-handler [req]
(do
(prn "coming to image handler")
(create-item-image req)
;; send the resourc whateverTheImageIdIsInTheDatabase.jpg created above.
(assoc (resource-response (str (:_id (:params req)) ".jpg") {:root ""})
:headers {"Content-Type" "image/jpeg; charset=UTF-8"})
)
)
但是这不起作用。资源已损坏。是因为资源是在创建文件之前发送的?如何即时发送资源?在磁盘上写入文件的另一个问题是它必须留在磁盘上。因此,如果发出1000个针对不同图像的请求,则所有1000个文件都将存储在服务器中,这是不必要的,因为它们已经在数据库中。最终,如何将存储为数据URL的这些图像作为文件发送到响应中,而不必先将它们写入磁盘?
资源是静态文件,不会在运行应用程序时改变,并且在编译服务器以进行生产时将它们打包到uberjar中。
如果要在响应中提供图像,只需将其转换为字节数组并在响应的:body中发送。