Vert.x學(xué)習(xí)筆記(二) Vert.x Web Client

本文參考自Vert.x Web Client官方文檔珊拼。套用官網(wǎng)的話(huà)來(lái)說(shuō),

Vert.x Web Client是一個(gè)異步的HTTP和HTTP/2網(wǎng)絡(luò)客戶(hù)端流炕。

相對(duì)來(lái)說(shuō)澎现,這是一個(gè)比較小的框架,而且功能也很直接每辟,做一個(gè)方便好用的HTTP客戶(hù)端剑辫。它具有以下功能:

  • Json body 編碼 / 解碼
  • request 參數(shù)
  • 統(tǒng)一的錯(cuò)誤處理
  • 表單提交

需要注意,它和Vertx核心包中的HttpClient有很多聯(lián)系渠欺。它繼承了HttpClient妹蔽,提供了更多功能。

引用類(lèi)庫(kù)

要使用這個(gè)類(lèi)庫(kù)很簡(jiǎn)單挠将。如果使用Maven胳岂,添加下面的依賴(lài)。

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-web-client</artifactId>
  <version>3.4.2</version>
</dependency>

如果使用Gradle舔稀,添加下面的依賴(lài)乳丰。

dependencies {
  compile 'io.vertx:vertx-web-client:3.4.2'
}

創(chuàng)建客戶(hù)端

創(chuàng)建客戶(hù)端稍微有點(diǎn)不一樣。

WebClient client = WebClient.create(vertx);

如果要添加配置參數(shù)内贮,可以這樣做产园。

WebClientOptions options = new WebClientOptions()
  .setUserAgent("My-App/1.2.3");
options.setKeepAlive(false);
WebClient client = WebClient.create(vertx, options);

如果已經(jīng)有了HttpClient,可以重用它夜郁。

WebClient client = WebClient.wrap(httpClient);

發(fā)起請(qǐng)求

無(wú)請(qǐng)求體的請(qǐng)求

這是最簡(jiǎn)單的情況什燕,一般的GET、HEAD等請(qǐng)求都輸這種方式拂酣。

webClient.get("www.baidu.com", "/")
        .send(ar -> {
            if (ar.succeeded()) {
                HttpResponse<Buffer> response = ar.result();
                System.out.println(response.body());
            } else {
                System.out.println(ar.cause());
            }
        });

如果要攜帶查詢(xún)參數(shù)秋冰,可以采用流式API。

client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .addQueryParam("param", "param_value")
  .send(ar -> {});

也可以直接在URL中設(shè)置查詢(xún)參數(shù)婶熬。

HttpRequest<Buffer> request = client.get(8080, "myserver.mycompany.com", "/some-uri");

// 添加參數(shù)1
request.addQueryParam("param1", "param1_value");

// 用URL覆蓋參數(shù)
request.uri("/some-uri?param1=param1_value&param2=param2_value");

添加請(qǐng)求體

假如使用POST方式傳遞參數(shù)剑勾,或者上傳圖片等,就需要帶有請(qǐng)求體的請(qǐng)求了赵颅。這種情況下虽另,只需要額外使用sendXXX等方法添加要傳遞的請(qǐng)求體即可。

webClient.post("httpbin.org", "/post")
        .sendBuffer(Buffer.buffer("name=yitian&age=25"), ar -> {
            if (ar.succeeded()) {
                HttpResponse<Buffer> response = ar.result();
                System.out.println(response.body());
            }
        });

如果要發(fā)送的信息比較大饺谬,可以使用sendStream方法捂刺,使用流來(lái)傳輸數(shù)據(jù)。

client
  .post(8080, "myserver.mycompany.com", "/some-uri")
  .sendStream(stream, resp -> {});

Json請(qǐng)求體

有時(shí)候可能需要發(fā)送Json數(shù)據(jù)募寨,這時(shí)候可以使用sendJsonObject方法族展。

client
  .post(8080, "myserver.mycompany.com", "/some-uri")
  .sendJsonObject(new JsonObject()
    .put("firstName", "Dale")
    .put("lastName", "Cooper"), ar -> {
    if (ar.succeeded()) {
      // Ok
    }
  });

發(fā)送表單

發(fā)送表單使用sendForm方法。

MultiMap multiMap = MultiMap.caseInsensitiveMultiMap();
multiMap.add("name", "yitian");
multiMap.add("age", "25");
webClient.post("httpbin.org", "/post")
        .sendForm(multiMap, ar -> {
            if (ar.succeeded()) {
                HttpResponse<Buffer> response = ar.result();
                System.out.println(response.body());
            }
        });

默認(rèn)表單使用application/x-www-form-urlencoded類(lèi)型的Content Type發(fā)送拔鹰,也可以修改成multipart/form-data類(lèi)型仪缸。

client
  .post(8080, "myserver.mycompany.com", "/some-uri")
  .putHeader("content-type", "multipart/form-data")
  .sendForm(form, ar -> {
    if (ar.succeeded()) {
      // Ok
    }
  });

目前上傳文件還不支持,將會(huì)在以后的版本中支持上傳文件列肢。

修改請(qǐng)求頭

可以添加和修改要發(fā)送的請(qǐng)求頭恰画。

HttpRequest<Buffer> request = client.get(8080, "myserver.mycompany.com", "/some-uri");
MultiMap headers = request.headers();
headers.set("content-type", "application/json");
headers.set("other-header", "foo");

也可以調(diào)用putHeader方法直接添加請(qǐng)求頭。

HttpRequest<Buffer> request = client.get(8080, "myserver.mycompany.com", "/some-uri");
request.putHeader("content-type", "application/json");
request.putHeader("other-header", "foo");

重用請(qǐng)求

如果需要對(duì)同一個(gè)地址發(fā)起多次請(qǐng)求瓷马,我們可以設(shè)置一次請(qǐng)求拴还,然后重復(fù)使用它。

HttpRequest<Buffer> get = client.get(8080, "myserver.mycompany.com", "/some-uri");
get.send(ar -> {
  if (ar.succeeded()) {
    // Ok
  }
});

// 重復(fù)使用
get.send(ar -> {
  if (ar.succeeded()) {
    // Ok
  }
});

超時(shí)

發(fā)起請(qǐng)求的時(shí)候可以設(shè)置超時(shí)值欧聘,單位是毫秒片林。

client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .timeout(5000)
  .send(ar -> {
    if (ar.succeeded()) {
      // Ok
    } else {
      // Might be a timeout when cause is java.util.concurrent.TimeoutException
    }
  });

處理請(qǐng)求

處理請(qǐng)求也是異步的。這里的ar類(lèi)型實(shí)際是AsyncResult的類(lèi)型怀骤,代表異步結(jié)果费封。如果結(jié)果成功了,調(diào)用result()方法返回HttpResponse<Buffer>類(lèi)型對(duì)象晒喷,這就是我們發(fā)起請(qǐng)求的結(jié)果孝偎,調(diào)用statusCode()body()等方法就可以查看相應(yīng)結(jié)果了凉敲。

webClient.get("www.baidu.com", "/")
        .send(ar -> {
            if (ar.succeeded()) {
                HttpResponse<Buffer> response = ar.result();
                System.out.println(response.body());
            } else {
                System.out.println(ar.cause());
            }
        });

解碼響應(yīng)

前面的響應(yīng)是以Buffer形式返回的衣盾。如果我們確定響應(yīng)是普通字符串、Json對(duì)象爷抓、可以和Json映射的POJO類(lèi)以及WriteStream势决,我們還可以解碼響應(yīng)。例如下面就將響應(yīng)體解碼為了JsonObject對(duì)象蓝撇。

webClient.post("httpbin.org", "/post")
        .as(BodyCodec.jsonObject())
        .sendBuffer(Buffer.buffer("name=yitian&age=25"), ar -> {
            if (ar.succeeded()) {
                HttpResponse<JsonObject> response = ar.result();
                System.out.println(response.body());
            }
        });

BodyCodec類(lèi)還有另外幾個(gè)方法果复,可以將響應(yīng)體解碼為不同類(lèi)型。假如響應(yīng)體比較大渤昌,可以直接將響應(yīng)體轉(zhuǎn)換為輸出流虽抄,以后慢慢讀取走搁。

client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .as(BodyCodec.pipe(writeStream))
  .send(ar -> {
    if (ar.succeeded()) {

      HttpResponse<Void> response = ar.result();

      System.out.println("Received response with status code" + response.statusCode());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

如果確定不需要響應(yīng)體,可以直接用none()方法扔掉響應(yīng)體迈窟。

client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .as(BodyCodec.none())
  .send(ar -> {
    if (ar.succeeded()) {

      HttpResponse<Void> response = ar.result();

      System.out.println("Received response with status code" + response.statusCode());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

當(dāng)然私植,如果響應(yīng)體還是解碼為Buffer,我們?nèi)匀豢梢哉{(diào)用bodyAsXXX方法來(lái)解碼響應(yīng)體车酣。這種方法僅適用于Buffer響應(yīng)體曲稼。

client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .send(ar -> {
    if (ar.succeeded()) {

      HttpResponse<Buffer> response = ar.result();

      // Decode the body as a json object
      JsonObject body = response.bodyAsJsonObject();

      System.out.println("Received response with status code" + response.statusCode() + " with body " + body);
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

使用HTTPS

前面使用的都是普通的HTTP,如果要使用HTTPS連接也很容易湖员,將端口號(hào)指定為443即可贫悄。

client
  .get(443, "myserver.mycompany.com", "/some-uri")
  .ssl(true)
  .send(ar -> {
    if (ar.succeeded()) {
      // Obtain response
      HttpResponse<Buffer> response = ar.result();

      System.out.println("Received response with status code" + response.statusCode());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

或者使用絕對(duì)路徑標(biāo)志的URI也可以。

client
  .getAbs("https://myserver.mycompany.com:4043/some-uri")
  .send(ar -> {
    if (ar.succeeded()) {
      // Obtain response
      HttpResponse<Buffer> response = ar.result();

      System.out.println("Received response with status code" + response.statusCode());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

官方文檔的最后還介紹了RxJava的一些集成娘摔。不過(guò)由于我還沒(méi)學(xué)習(xí)過(guò)RxJava窄坦,所以這部分就不介紹了。有興趣的同學(xué)可以查閱相關(guān)資料來(lái)進(jìn)行自學(xué)晰筛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嫡丙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子读第,更是在濱河造成了極大的恐慌曙博,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怜瞒,死亡現(xiàn)場(chǎng)離奇詭異父泳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吴汪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)惠窄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人漾橙,你說(shuō)我怎么就攤上這事杆融。” “怎么了霜运?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵脾歇,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我淘捡,道長(zhǎng)藕各,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任焦除,我火速辦了婚禮激况,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己乌逐,他們只是感情好竭讳,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著黔帕,像睡著了一般代咸。 火紅的嫁衣襯著肌膚如雪蹈丸。 梳的紋絲不亂的頭發(fā)上成黄,一...
    開(kāi)封第一講書(shū)人閱讀 52,166評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音逻杖,去河邊找鬼奋岁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛荸百,可吹牛的內(nèi)容都是我干的闻伶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼够话,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蓝翰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起女嘲,我...
    開(kāi)封第一講書(shū)人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤畜份,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后欣尼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體爆雹,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年愕鼓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钙态。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡菇晃,死狀恐怖册倒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情磺送,我是刑警寧澤驻子,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站册着,受9級(jí)特大地震影響拴孤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甲捏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一演熟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦芒粹、人聲如沸兄纺。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)估脆。三九已至,卻和暖如春座云,著一層夾襖步出監(jiān)牢的瞬間疙赠,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工朦拖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留圃阳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓璧帝,卻偏偏與公主長(zhǎng)得像捍岳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子睬隶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容