Clojure世界:Http Client

栏目: 编程语言 · Clojure · 发布时间: 5年前

使用http client提交表单或者下载网页也是非常常见的任务,比如使用 Java 的时候可以用标准库的HttpURLConnection,也可以选择 Apache Http Client 。在clojure里也有这样的类库,这里我将介绍三个各有特色的http client实现。

首先,我最先推荐使用clj-http这个类库,它是Apache HttpClient的clojure wrapper,是一个提供同步API的简单易用的Http Client。

名称: clj-http

主页: https://github.com/dakrone/clj-http

依赖:

[clj - http  " 0.3.1 " ]

例子:

(require  ' [clj-http.client :as client])
(client / get  " http://google.com " )

结果:

=>

{:cookies {"NID" {:domain ".google.com.hk", :expires #<Date Tue Aug 14 18:20:38 CST 2012>, :path "/", :value "56=qn2OWtODE2D3fUKi_vbi44jZepOeLI9xC4Ta1JQLEicqUvIZAqr7TCmft_hq8i_FRwnFXdTK1jV2S5IrSZFyYhlAN2KcQEXgWX1iK36gM2iYPaKPihuUZDCqgiAamDOl", :version 0}, "PREF" {:domain ".google.com.hk", :expires #<Date Wed Feb 12 18:20:38 CST 2014>, :path "/", :value "ID=8b73a654ff0a2783:FF=0:NW=1:TM=1329128438:LM=1329128438:S=uEM4SsFuHlkqtVhp", :version 0}},

:status 

200
    :headers { " date "   " Sun, 01 Aug 2010 07:03:49 GMT "                " cache-control "   " private, max-age=0 "                " content-type "   " text/html; charset=ISO-8859-1 "
               Clojure世界:Http Client

}

:body 

" <!doctype html> Clojure世界:Http Client "     :trace - redirects [ " http://google.com "   " http://www.google.com/ "   " http://www.google.fr/ " ]}

更多例子:

(client / get  " http://site.com/resources/3 "

{:accept :json})

;; Various options:

(client

/ post  " http://site.com/api "
  {:basic - auth [ " user "   " pass "

]

:body 

" {\ " json\ " : \ " input\ " } "
   :headers { " X-Api-Version "   " 2 "

}

:content

-

type :json

:socket

- timeout  1000
   :conn - timeout  1000

:accept :json})

;; Need to contact a server with an untrusted SSL cert

? (client / get  " https://alioth.debian.org "  {:insecure ?   true

})

;; If you don

' t want to follow-redirects automatically:

(client / get  " http://site.come/redirects-somewhere "  {:follow - redirects  false

})

;; Only follow a certain number of redirects:

(client

/ get  " http://site.come/redirects-somewhere "  {:max - redirects  5

})

;; Throw an exception 

if

redirected too many times:

(client

/ get  " http://site.come/redirects-somewhere "  {:max - redirects  5  : throw - exceptions  true

})

;; Send form params as a urlencoded body

(client

/ post  " http//site.com "  {:form - params {:foo  " bar "

}})

;; Multipart form uploads

/

posts

;; a map or vector works as the multipart object. Use a vector of

;; vectors 

if

you need to preserve order, a map otherwise.

(client

/ post  " http//example.org "  {:multipart [[ " title "   " My Awesome Picture "

]

[

" Content/type "   " image/jpeg "

]

[

" file "  (clojure.java.io / file  " pic.jpg "

)]]})

;; Multipart values can be one of the following:

;; String, InputStream, File, or a 

byte -

array

;; Basic authentication

(client

/ get  " http://site.com/protected "  {:basic - auth [ " user "   " pass "

]})

(client

/ get  " http://site.com/protected "  {:basic - auth  " user:pass "

})

;; Query parameters

(client

/ get  " http://site.com/search "  {:query - params { " q "   " foo, bar " }})

clj-http的API相当的简洁漂亮,使用起来非常便利,强烈推荐。题外,学习clojure的一个好方法就是为现有的java类库实现一些方便的clojure wrapper。

如果你需要异步的http client,我会推荐http.async.client这个类库,它的API是异步形式的类似 Java的Future模式,对于clojure程序员来说应该更像是agent。

名称:http.async.client

主页: https://github.com/neotyk/http.async.client

依赖:

[http.async.client  " 0.4.1 " ]

例子:

(require  ' [http.async.client :as c])
(with - open [client (c / create -

client)]

(let [response (c

/ GET client  " http://neotyk.github.com/http.async.client/ "

)]

(prn (c

/ done ?

response))

(c

/

await response)

(prn (c

/

string response))

(prn (c

/

status response))

(prn (c

/ done ?  response))))

输出:

false
<! DOCTYPE html  Clojure世界:Http Client Clojure世界:Http Client {:code  200 , :msg  " OK " , :protocol  " HTTP/1.1 " , :major  1 , :minor  1

}

true

更多例子:

(c / POST client  " http://example.com "  :body  " hello world "  :timeout  3000

)

(c

/ DELETE client  " http://example.com "

)

(c

/ POST client  " http://example.com "  :body  " hello world "  :auth {:type :basic :user  " admin "  :password  " admin " })

请注意,这些方法都是异步调用的,你需要通过await来等待调用完成,或者通过done?来判断调用是否完成。

http.async.client有个比较重要的特性就是对Http Chunked编码的支持,分别通过LazySeq和callback的方式支持,首先看将Http chunked变成一个lazy seq:

(with - open [client (client / create -

client)] ; Create client

(let [resp (client

/ stream -

seq client :get url)]

(doseq [s (s

/

string resp)]

(println s))))

这里非常关键的一点是stream-seq返回的chunk序列,每取一个就少一个(通过first函数),也就是说每次调用first取到的chunk都不一样,是顺序递增,不可重复获取的。

通过callback方式处理:

(with - open [client (client / create -

client)] ; Create client

(let [parts (ref #{})

resp (client

/ request -

stream client :get url

(fn [state body]

(dosync (alter parts conj (string body)))

[body :

continue

]))]

;; 

do

something to @parts

))

自己传入一个callback函数接收chunk,比如这里用一个ref累积。

http.async.client的详细文档看这里: http://neotyk.github.com/http.async.client/docs.html

最后,有兴趣还可以看下 aleph 这个异步通讯的框架,它支持Http协议,也提供了http server和client的实现。不过它的API就没有那么简单明了,它的模型是类似 go 语言里利用channel做异步通讯的模型,http只是它的一个模块罢了,这是另一个话题了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

伟大创意的诞生

伟大创意的诞生

史蒂文·约翰逊 (Steven Johnson) / 盛杨燕 / 浙江人民出版社 / 2014-8-1 / CNY 52.90

 大家都认得出好创意。印刷机、铅笔、抽水马桶、电池、互联网、GPS、Google——这些都是绝妙的创意。然而,它们是如何产生的?被喻为“科技界的达尔文”的作者,在《伟大创意的诞生》一书中,提供了深具启示意义以及有论证实据的答案。  作者史蒂文•约翰逊以富有感染力、包罗万象的风格游历于多重领域,从神经生物学、都市研究,到网络文化,找出了独特创新背后的7大关键模式,深入人类600年重要发明的......一起来看看 《伟大创意的诞生》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具