September 1, 2019
By: Dirk

Clojure 文件上传接口部分

文件上传是日常开发中的常用操作,一般采用 multipart 的方式,即 content-type 为 multipart/form-data。multipart 可以在上传文件的同时携带其他信息,最终会将这些信息作为一个整体提交给接口服务。

框架中使用 reitit 进行路由管理,reitit 提供了Multipart Request Handling 中间件来处理文件上传,此中间件为reitit的一个默认中间件。Multipart Request Handling 中间件提供了一个 [:parameters :multipart] key 值来接收客户端提交过来的数据。

文件上传分为两种情况,单文件上传与多文件上传,无论采用哪种上传方式,接口服务都需要先配置 reitit 中间件,现在的框架中是在 base.clj 文件中进行配置的,感兴趣的同学自己去学习下吧。

对于单文件上传,接收参数的方式为:

["/upload"
    {:post {:summary "文件上传"
            :parameters {:multipart {:file multipart/temp-file-part
                                     :file_prefix string?}}
            :handler (fn [{{{:keys [file file_prefix]} :multipart}:parameters}]
                       (success))}}]

其中 file 及 file_prefix 为参数名称。

在 swagger-ui 中可以直接进行测试

swagger-single-file

对于多文件上传,接收参数的方式为:

["/upload/multi"
    {:post {:summary "多文件上传"
            :parameters {:multipart {:files (s/coll-of multipart/temp-file-part)
                         :file_prefix string?}}
            :handler (fn [{{{:keys [files file_prefix]} :multipart} :parameters
                          }]
                       (success))}}]

files 指定为 s/coll-of 表示为一个集合,也可以使用 [multipart/temp-file-part] 的方式。

在 swagger-ui 中的展示如下,暂时不可直接进行测试,需要借助于 Postman 或 Curl 来进行测试

swagger-multiple-file-err

尝试过解决(参考资料),手动修改 html 源码,展示成功,尚未找到如何配置。

swagger-multiple-file-err

文件上传后如何对文件进行操作呢?以单文件为例文件上传后request map 结构如下(如果是多文件则是 files 数组):

{:multipart {"file_prefix": "xxx"
             "file" {:filename "xxx"
                     :content-type "xxx"
                     :tempfile #object[java.io.FIle ...]
                     :size xx}}}

:filename - 上传文件名称

:content-type - 上传文件类型 (MIME TYPE)

:tempfile - 上传的文件

:size - 上传文件的大小

通过 ring 提供的以上4个参数对文件进行操作,文档传送门

比如获取文件的后缀名可以通过以下方法

(let [filename (:filename file)]
    (subs filename (clojure.string/last-index-of filename "." (count filename)))
Tags: clojure