眾里尋他千百度
正如Groovy對(duì)Java很多特性進(jìn)行的包裝優(yōu)化一樣点寥,基于Groovy的HttpBuilder也包裹了HttpClient,使網(wǎng)絡(luò)編程變得更加的方便易用场钉,下面稍微來(lái)用一個(gè)例子看一下蚊俺。
尋找各種依賴(lài)的jar包有時(shí)候會(huì)讓我們失去耐心,不過(guò)值得慶幸的是我們有Maven和Gradle這樣的工具逛万,可以根據(jù)配置輕松的幫我們配置好我們需要的數(shù)據(jù)泳猬。下面我們來(lái)敘述一下整個(gè)過(guò)程。
- 創(chuàng)建文件夾httpbuildertest
- 創(chuàng)建gradle配置文件,build.gradle得封,內(nèi)容如下:
<pre>
apply plugin: "groovy"
apply plugin: "eclipse"
repositories {
mavenCentral()
}
dependencies {
compile "org.codehaus.groovy:http-builder:0.4.0"
compile "org.codehaus.groovy:groovy-all:2.3.3"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}
</pre>
gradle我們將做另文介紹
執(zhí)行g(shù)ralde eclipse(當(dāng)然必須先安裝gradle)埋心,就可以生成eclipse所需要的.classpath和.project文件,這時(shí)候就可以使用eclipse導(dǎo)入功能來(lái)import->Existing Projects Into WorkSpace忙上。
-
創(chuàng)建我們的一個(gè)測(cè)試拷呆,試試看是不是可以使用httpbuilder了
import groovyx.net.http.HTTPBuilder
import spock.lang.Specification;
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*class HttpbuildLabSpec extends Specification{
HTTPBuilder http = new HTTPBuilder( 'http://m.weather.com.cn' )
public void testRequestWeather(){
when:
def info =""
http.request( GET, JSON ) {
url.path = '/data/101290401.html'
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
response.success = { resp, json ->
info = json.weatherinfo.city
}
response.failure = { resp -> println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}" }
}
then: "曲靖"==info
}
}
打完收工,通過(guò)這個(gè)小例子我們可以了解到這么一些內(nèi)容:
(1)HTTPBuilder 是這個(gè)框架的核心類(lèi)(要不然怎么和框架一個(gè)名字)疫粥,構(gòu)建這個(gè)類(lèi)的對(duì)象的時(shí)候茬斧,指定要請(qǐng)求的baseUrl。
(2)request方法可以指定請(qǐng)求的method和返回的數(shù)據(jù)格式手形,method對(duì)應(yīng)的是GET/PUT/POST/DELETE/HEAD幾個(gè)常量啥供,而數(shù)據(jù)格式目前有JSON/XML/HTML/BINARY/URLENC/ANY幾種。
(3)一個(gè)比較有意思的地方是库糠,在http的request方法里面伙狐,仿佛是無(wú)根之水一樣突然冒出來(lái)了幾個(gè)沒(méi)有聲明過(guò)的變量,看起來(lái)連編譯也不會(huì)通過(guò)的方法瞬欧,那么是如何能正常運(yùn)作的呢贷屎?這個(gè)我們就要研究到Groovy的Closure(閉包)。Groovy的閉包里包含有一個(gè)delegate屬性艘虎,一般來(lái)說(shuō)唉侄,這個(gè)delegate里保存的是閉包使用上下文的對(duì)象引用,比如a調(diào)用了一個(gè)閉包b野建,則b的delegate就是a的this對(duì)象属划。而在HTTPBuilder對(duì)象調(diào)用request方法的時(shí)候,它把傳入閉包的delegate改成了一個(gè)叫做SendDelegate的類(lèi)對(duì)象(這是HTTPBuilder的內(nèi)部類(lèi)候生,他們都是用Java寫(xiě)的同眯,在新版的HttpBuilder里,已經(jīng)改名為RequestConfigDelegate)唯鸭,這個(gè)類(lèi)里面须蜗,分別包含了一個(gè)叫做getHeaders()的方法,一個(gè)叫做getUrL()的方法目溉,一個(gè)叫做getResponse()的方法明肮。稍微思索一下我們就可以想到,Groovy里有這樣的特性缭付,如果直接使用一個(gè)識(shí)別不出來(lái)的變量柿估,Groovy會(huì)假設(shè)它是getter的一種簡(jiǎn)寫(xiě)形式,自動(dòng)進(jìn)行補(bǔ)全(當(dāng)然這也是DSL的常用伎倆陷猫,把方法偽裝成短語(yǔ))官份,而getter并沒(méi)有參數(shù)只厘,所以其括號(hào)是可以簡(jiǎn)寫(xiě)的,實(shí)際上上面的代碼可以寫(xiě)作getUrl().path = '/data/101290401.html'舅巷,這樣就非常符合程序員的視覺(jué)體驗(yàn)了羔味。
(4)第四點(diǎn)羅嗦了不少,主要是為了喜歡追根問(wèn)題的同學(xué)釋疑钠右,實(shí)際上整個(gè)調(diào)用還是非常的簡(jiǎn)單明快的赋元,在request閉包里,我們通過(guò)response(記得嗎飒房,實(shí)際上就是GetResponse()),獲得了一個(gè)Map結(jié)構(gòu)搁凸,這個(gè)Map的內(nèi)部結(jié)構(gòu)實(shí)際上是Map<String,Closure>,對(duì)“success”和“failure”這兩個(gè)key我們分別設(shè)置了對(duì)應(yīng)的閉包,這樣就完成了回調(diào)的設(shè)置狠毯,一旦方法成功或者失敗护糖,就可以調(diào)用到對(duì)應(yīng)的閉包。
(5)使用了JSON作為返回格式嚼松,閉包的第二個(gè)參數(shù)就是解析好的返回body嫡良,就是一個(gè)Json對(duì)象,是可以直接用點(diǎn)號(hào)來(lái)訪(fǎng)問(wèn)的献酗。當(dāng)然最好不要在失敗的閉包里放這個(gè)參數(shù)寝受,一般失敗的情況比較多,也許就是一個(gè)html返回罕偎,格式錯(cuò)誤那么測(cè)試也就無(wú)法按照預(yù)期進(jìn)行了很澄。
簡(jiǎn)單的一個(gè)例子,希望能幫到讀者颜及。