如何在Clojure中动态创建文件资源



我有一个包含图像的数据库,我想通过一些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中。

如果您想为响应提供一个映像,只需将其转换为字节数组并在:响应体中发送即可。

最新更新