How do I save a file uploaded via POST and multipart/form-data
? For example, the following resource reports an error:
(resource
{:methods {:post {:consumes "multipart/form-data"
:parameters {:form {:photo java.io.File}}
:response
(fn [ctx]
(let [photo (-> ctx :parameters :form :photo)]
(->> "photo.jpg"
(io/file "resources" "passengers")
(io/copy photo))))}}})
The error is:
Bad form fields
{:status 400,
:error
{:photo (not (instance? java.io.File a-yada.multipart.DefaultPart))}}
io
is an alias for <http://clojure.java.io|clojure.java.io>
; I tried a similar implementation with an io/writer
inside a with-open
clause but got No matching method found: write for class java.io.BufferedWriter
errors, so tried io/copy
instead to see what that would show up.
How do I use the multipart data? I see there’s a process-request-body
method implementation for multi-part bodies in yada.multipart
but I’ve no idea how to invoke it (or why isn’t it being invoked on my behalf by yada when it sees the content type?)Setting the content-type to application/octet-stream
instead works fine, but it’d be great to know what I was doing wrong with the mulitpart/form-data
content-type payload (if only so I can POST
forms that include photos or other binary payloads in the future)
If I follow an example I found and implement a :consumer
entry on the resource, the file of the correct size is created, but it’s not parseable as an image (I’m uploading a jpg and giving it that file extension):
:consumer (fn [ctx _ body-stream]
(let [file (io/file "resources" "passengers" "photo.jpg"))]
(yada.consume/save-to-file ctx body-stream file)))
The example is from https://github.com/thegeez/clj-wiki/blob/64c0cab29a360b8233df6e179309f5017af65d88/src/net/thegeez/wiki/fs2.clj