Jitendra
Jitendra

Reputation: 51

How to create a multipart request in clojure using clj-http api

I want to create a multipart HTTP request using clj-http. Multipart request is below:

--Boundary

Content-Type: text/xml; charset=UTF-8

Content-Id id1

xml1

--Boundary
Content-Type: text/xml; charset=UTF-8
Content-Id id2

xml2

--Boundary--

I am using this Clojure code to build the multipart request:

(post "url"
      {:multipart [{:name "XML1"
                    :content Xml1
                    :encoding "UTF-8"
                    :mime-type "text/xml"}
                   {:name "XML2"
                    :content Xml2
                    :encoding "UTF-8"
                    :mime-type "text/xml"}]})

How can I add Content-Id in the multipart?

Upvotes: 4

Views: 2129

Answers (2)

Jitendra
Jitendra

Reputation: 51

:name attribute is used to give the name of entity i.e 1st content of multipart and so on.

Clojure is lacking this features to add the content id in multipart request. However, in clojure, clj-http client internally uses the http-client api to build the multipart request. See this link on how to create multipart in clj-http.

clj-http client is not using content id anywhere. So, one thing is clear, we can not create multipart request with content-id.

One solution I found, just import http-client package in clojure and create multipart request. No need to download any http-client jar, as I told clj-http using http-client as dependency.

(:import  (java.nio.charset Charset)
            (org.apache.http.entity.mime MultipartEntity)
            (org.apache.http.entity.mime FormBodyPart)
            (org.apache.http.entity.mime HttpMultipartMode)
            (org.apache.http.entity.mime.content
             ByteArrayBody
             FileBody
             InputStreamBody
             StringBody))

Just use below function template to create your own request. And give multipart object as :body for http request. But, it is not pure clojure implementation. It is temporary solution.

(defn build-form-body [formbody content cid]
  (let [sb (StringBody. content "text/xml" (Charset/forName "utf-8"))]
    (let [fb (FormBodyPart. formbody , sb)]
    (.addField fb "Content-Id" cid)
    fb)))

(defn build-multipart []
  (let [mp-entity (MultipartEntity.)]
    (.addPart mp-entity (make-form-body "formbody1" Xml1 "content-id1-val"))
    (.addPart mp-entity (make-form-body "formbody2" Xml2 "content-id1-val2"))
    mp-entity))

Note: give correct content type. In my case it is xml,so for me "text/xml" and string body. If file then content type will change and use FileBody so on.

Hope it will help you.

Upvotes: 1

llj098
llj098

Reputation: 1412

If you treat the Content-Id as a header, add :Content-Id "Id 1" to your request map should help, change to :

{:name "XML1"
:content Xml1
:Content-Id "Id 1"
:encoding "UTF-8"
:mime-type "text/xml"}

If you treat Content-Id as body, just put it in to body

Upvotes: 0

Related Questions