成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vert.x 3.4.x 之 Web Client

selfimpr / 3511人閱讀

摘要:為此我們可以使用來發(fā)送一個(gè)比如流,會(huì)自動(dòng)為我們實(shí)現(xiàn)管道傳輸數(shù)據(jù)。因?yàn)榱鞯拈L(zhǎng)度不確定,請(qǐng)求將使用即分塊傳輸。方法可以被多次安全的調(diào)用,這對(duì)于無數(shù)據(jù)的請(qǐng)求很容易復(fù)用配置和。如此在接受響應(yīng)的回調(diào)函數(shù)里可以直接得到設(shè)置的響應(yīng)解碼體。

本文主要介紹Vert.x 3.4.x 版本新組件Web Client的使用

Vert.x不久前發(fā)布了3.4.0 release版本,該版本在語言支持上新增了Scala和Kotlin的支持,新引入了Web Client和Kafka Client,同時(shí)加強(qiáng)了微服務(wù)組件的功能,支持多種集群管理器供開發(fā)者選擇(公司一位同事是vertx-zookeeper集群管理器的開發(fā)者),除了這些還有些些微的改動(dòng),比如Auth/Security方面的增強(qiáng),RxJava的支持增強(qiáng)等等,更多的請(qǐng)進(jìn)入傳送門。

本文不具體對(duì)每個(gè)新特性做分析,只針對(duì)Web Client做介紹,簡(jiǎn)單了解下3.4.x版本的Web Client和3.3.x版本的Http Client的差異。

可以明確的是Web Client是Http Client的升級(jí)版,他繼承了Http Client的功能特性比如配置,Http/2的支持,pipelining等,同時(shí)又提供了一些高級(jí)特性,比如表單提交、錯(cuò)誤處理、30X跳轉(zhuǎn)等。如果你不需要細(xì)粒度的處理http請(qǐng)求/響應(yīng),建議你使用Web Client,它已經(jīng)為你封裝了好了很簡(jiǎn)單的方法供你調(diào)用,很多API也都來自HttpClient。

使用Web Client前,你需要引入依賴


  io.vertx
  vertx-web-client
  3.4.1

創(chuàng)建一個(gè)默認(rèn)的WebClient:

WebClient client = WebClient.create(vertx);

創(chuàng)建一個(gè)可配置的WebClient:

WebClientOptions options = new WebClientOptions();
options.setDefaultHost("wonapi.maxleap.cn");
WebClient webClient = WebClient.create(vertx,options);

WebClientOption的配置項(xiàng)全部繼承了HttpClientOption,你可以配置其中任意選項(xiàng)。如果你的應(yīng)用中已經(jīng)使用了HttpClient并且配置了Option,你可以復(fù)用它:

WebClient client = WebClient.wrap(httpClient);

構(gòu)建一個(gè)無body數(shù)據(jù)的簡(jiǎn)單請(qǐng)求:

HttpRequest request = client.request(HttpMethod.GET,"/1.0/orders");
request.send(asyncResult -> {
  if (asyncResult.succeeded()) {
    HttpResponse response = asyncResult.result();
    System.out.println("status code:"+response.statusCode());
  } else {
    System.err.println("error:"+asyncResult.cause().getMessage());
  }
});

這適用于GET/OPTIONS/HEAD方式的請(qǐng)求,你可以設(shè)置request的query參數(shù),比如

通過request.addQueryParam("param1", "param1_value");來添加query參數(shù),也可以通過request.setQueryParam("param2", "another_param2_value");來覆蓋query參數(shù),你甚至可以通過request.uri("/1.0/orders?param1=param1_value2¶m2=param2_value")來放棄現(xiàn)有的query參數(shù)重新設(shè)置。

構(gòu)建一個(gè)有body數(shù)據(jù)的請(qǐng)求:

Buffer buffer = Buffer.buffer("{"a":1}");
HttpRequest request = client.request(HttpMethod.POST,"/1.0/orders");
httpRequest.sendBuffer(buffer,asyncResult -> {
  if (asyncResult.succeeded()) {
    HttpResponse response = asyncResult.result();
    System.out.println("status code:"+response.statusCode());
  } else {
    System.err.println("error:"+asyncResult.cause().getMessage());
  }
});

上面send方法來發(fā)送無body數(shù)據(jù)的請(qǐng)求,而通過sendXXX方法可以發(fā)送一個(gè)帶body數(shù)據(jù)的請(qǐng)求。
sendBuffer 用來發(fā)送一個(gè)buffer緩沖區(qū)數(shù)據(jù),這個(gè)很有用,但通常我們不希望將內(nèi)容全部加載到內(nèi)存里,因?yàn)樗赡芎艽?,或者我們想處理很多并發(fā)請(qǐng)求,并且希望對(duì)每個(gè)請(qǐng)求使用最小值。
為此我們可以使用sendStream來發(fā)送一個(gè)ReadStream(比如AsyncFile)流,WebClient會(huì)自動(dòng)為我們實(shí)現(xiàn)管道傳輸pump數(shù)據(jù)。因?yàn)榱鞯拈L(zhǎng)度不確定,請(qǐng)求將使用chunk即分塊傳輸。當(dāng)然如果知道流的大小,你需要指定content-length大小。

fs.open("content.txt", new OpenOptions(), fileRes -> {
  if (fileRes.succeeded()) {
    ReadStream fileStream = fileRes.result();

    String fileLen = "1024";

    // Send the file to the server using POST
    client
      .post(80, "api.maxleap.cn", "/2.0/files")
      .putHeader("content-length", fileLen)
      .sendStream(fileStream, ar -> {
        if (ar.succeeded()) {
          // Ok
        }
      });
  }
});

上面就是發(fā)送一個(gè)本地文件content.txt到服務(wù)器,通過流傳輸?shù)姆绞?,因?yàn)橹牢募笮∷詻]有使用chunked分塊傳輸。

sendJsonObject 用來發(fā)送一個(gè)json格式數(shù)據(jù),使用它WebClient為自動(dòng)為你設(shè)置Content-Typeapplication/json。比如:

request.sendJsonObject(new JsonObject().put("name","Jack").put("age",18));

sendJson 用來發(fā)送一個(gè)POJO,本質(zhì)上是通過Json.encode來將對(duì)象轉(zhuǎn)化為json字符串(通過Jackson實(shí)現(xiàn))。比如:

request.sendJson(new User("jack",18));

sendForm 用來發(fā)送表單數(shù)據(jù),使用它WebClient會(huì)自動(dòng)為你設(shè)置Content-Typeapplication/x-www-form-urlencoded。你也可以設(shè)置Content-Typemultipart/form-data,但當(dāng)前版本(目前3.4.1)不支持表單文件上傳,表單文件上傳將會(huì)在后續(xù)的API版本中支持。比如:

MultiMap form = MultiMap.caseInsensitiveMultiMap();
form.set("name","jack");
form.set("age","18");
client
  .post(80, "api.maxleap.cn", "/2.0/users")
  .putHeader("content-type", "multipart/form-data")
  .sendStream(fileStream, ar -> {
    if (ar.succeeded()) {
      // Ok
    }
  });

跟HttpClient的API類似,你可以通過request.putHeader("header1":"value1")來添加一條頭信息,也可以通過MultiMap headers = request.headers();來獲取頭信息并操作它(add,addAll,set,setAll,remove等操作)。

send方法可以被多次安全的調(diào)用,這對(duì)于無body數(shù)據(jù)的請(qǐng)求很容易復(fù)用配置和HttpRequest。同時(shí)你可以在request的基礎(chǔ)上修改請(qǐng)求,比如我要復(fù)用之前使用過的request,同時(shí)修改下頭信息,那么我們只需要調(diào)用之前的request對(duì)象的putHeader方法即可得到我們想要的新的request。

通過調(diào)用request.timeout(10000)你可以為請(qǐng)求設(shè)置數(shù)據(jù)讀取超時(shí)時(shí)間,如果請(qǐng)求在超時(shí)期限內(nèi)任未返回任何數(shù)據(jù),會(huì)將異常java.util.concurrent.TimeoutException傳遞給響應(yīng)處理程序。

send方法接受一個(gè)回調(diào)函數(shù),用來處理請(qǐng)求發(fā)送后異步接受響應(yīng)結(jié)果,需要注意的是默認(rèn)接受到的響應(yīng)數(shù)據(jù)會(huì)全部緩沖存放在內(nèi)存里(通過request.as(BodyCodec.buffer())設(shè)置),如果數(shù)據(jù)很大,建議你通過request.as(BodyCodec.pipe(writeStream))將響應(yīng)傳遞給寫入流中,你也可以通過BodyCodec實(shí)現(xiàn)你想要的響應(yīng)體解碼,比如request.as(BodyCodec.jsonObject())將響應(yīng)解析為JsonObject,request.as(BodyCodec.json(User.class))將響應(yīng)解析為POJO,如果你不關(guān)注響應(yīng)數(shù)據(jù),你可以通過request.as(BodyCodec.none())來忽略響應(yīng)體。如此在接受響應(yīng)的回調(diào)函數(shù)里可以直接得到request.as()設(shè)置的響應(yīng)解碼體。比如:

client
  .get(80, "api.maxleap.cn", "/2.0/users")
  .as(BodyCodec.json(User.class))
  .send(ar -> {
    if (ar.succeeded()) {
      HttpResponse response = ar.result();
      User user = response.body();
      System.out.println("Received response with status code" + response.statusCode() + " with body " + user.toString());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());
    }
  });

默認(rèn)情況下,你可以在處理響應(yīng)時(shí)直接使用bodyAsXXX()來解析成想要的響應(yīng)體,這只針對(duì)默認(rèn)的request.as(BodyCodec.buffer())有效。

vertx 3.3.x的HttpClient是不支持30X重定向的,需要自己實(shí)現(xiàn)跳轉(zhuǎn)邏輯,在3.4.x中WebClient默認(rèn)為我們實(shí)現(xiàn)了自動(dòng)重定向,我們可以在WebClientOption中配置30X重定向的配置:

WebClientOptions options = new WebClientOptions();
options
    .setFollowRedirects(true)//設(shè)置遵循重定向
    .setMaxRedirects(5);//最大重定向次數(shù)
WebClient webClient = WebClient.create(vertx,options);

Vert.x web client 可以跟HttpClient相同的方式使用https:

client
  .get(443, "api.maxleap.cn", "/2.0/users")
  .ssl(true)
  .send(ar -> {
    if (ar.succeeded()) {
      // OK
    } 
  });

或者直接通過決定路徑發(fā)起https請(qǐng)求:

client
  .getAbs("https://api.maxleap.cn/2.0/users")
  .send(ar -> {
    if (ar.succeeded()) {
      // OK
    } 
  });

Vert.x RxJava是一個(gè)非常受歡迎的響應(yīng)式編程擴(kuò)展程序包,3.4.X版本增強(qiáng)了對(duì)RxJava的支持,原本返回Observable的API全部更改為返回rx.Single,使其語義更加清晰,結(jié)合Vert.x Web Client,將會(huì)是一個(gè)非常強(qiáng)大的組合。

io.vertx.rxjava.core.Vertx rxVertx = io.vertx.rxjava.core.Vertx.vertx();
io.vertx.rxjava.ext.web.client.WebClient rxWebClient = io.vertx.rxjava.ext.web.client.WebClient.create(rxVertx);
rxWebClient.get(80,"api.maxleap.cn","/2.0/users")
    .putHeader("header1","header1-value")
    .addQueryParam("query1","query1-value")
    .as(io.vertx.rxjava.ext.web.codec.BodyCodec.jsonObject())
    .rxSend()
    .subscribe(response -> {}, Throwable::printStackTrace);

rxSend方法返回一個(gè)Single>,它能在訂閱一個(gè)Single請(qǐng)求事件后發(fā)送該請(qǐng)求,它能被多次訂閱。

作者信息
原文系力譜云旗下技術(shù)團(tuán)隊(duì)_云服務(wù)研發(fā)成員:David Young
首發(fā)鏈接:https://blog.maxleap.cn/archi...

相關(guān)文章
Maxleap Vert.x應(yīng)用實(shí)踐總結(jié)
次時(shí)代Java編程(一):續(xù) vertx-sync實(shí)踐
使用Vert.x構(gòu)建Web服務(wù)器和消息系統(tǒng)

歡迎關(guān)注微信公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66998.html

相關(guān)文章

  • Vert.x入坑須知(4

    摘要:主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。以應(yīng)用為例,由于實(shí)際上是在上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請(qǐng)求全部無法得到處理。因此,最合適的做法就是對(duì)于簡(jiǎn)單業(yè)務(wù),采用異步庫(kù)。本系列其他文章入坑須知入坑須知入坑須知 最開始覺得這個(gè)系列也就最多3篇了不起了(因?yàn)槭虏贿^三嘛),沒曾想居然迎來了第四篇! Kotlin 由于最近決定投身到區(qū)塊鏈的學(xué)習(xí)當(dāng)中的緣故,出于更好的理解它的基本概念,自...

    summerpxy 評(píng)論0 收藏0
  • Vert.x Blueprint 系列教程(二) | 開發(fā)基于消息的應(yīng)用 - Vert.x Kue

    摘要:本文章是藍(lán)圖系列的第二篇教程。這就是請(qǐng)求回應(yīng)模式。好多屬性我們一個(gè)一個(gè)地解釋一個(gè)序列,作為的地址任務(wù)的編號(hào)任務(wù)的類型任務(wù)攜帶的數(shù)據(jù),以類型表示任務(wù)優(yōu)先級(jí),以枚舉類型表示。默認(rèn)優(yōu)先級(jí)為正常任務(wù)的延遲時(shí)間,默認(rèn)是任務(wù)狀態(tài),以枚舉類型表示。 本文章是 Vert.x 藍(lán)圖系列 的第二篇教程。全系列: Vert.x Blueprint 系列教程(一) | 待辦事項(xiàng)服務(wù)開發(fā)教程 Vert.x B...

    elina 評(píng)論0 收藏0
  • Vert.x Blueprint 系列教程(一) | 待辦事項(xiàng)服務(wù)開發(fā)教程

    摘要:本文章是藍(lán)圖系列的第一篇教程。是事件驅(qū)動(dòng)的,同時(shí)也是非阻塞的。是一組負(fù)責(zé)分發(fā)和處理事件的線程。注意,我們絕對(duì)不能去阻塞線程,否則事件的處理過程會(huì)被阻塞,我們的應(yīng)用就失去了響應(yīng)能力。每個(gè)負(fù)責(zé)處理請(qǐng)求并且寫入回應(yīng)結(jié)果。 本文章是 Vert.x 藍(lán)圖系列 的第一篇教程。全系列: Vert.x Blueprint 系列教程(一) | 待辦事項(xiàng)服務(wù)開發(fā)教程 Vert.x Blueprint 系...

    frank_fun 評(píng)論0 收藏0
  • 次時(shí)代Java編程(一):續(xù) vertx-sync實(shí)踐

    摘要:定時(shí)器例子之前通過調(diào)用定時(shí)器,需要傳一個(gè)回調(diào),然后所有的代碼邏輯都包在里面。這里定時(shí)器會(huì)阻塞在這一行,直到一秒后才會(huì)執(zhí)行下面的一行。 之前介紹過quasar,如果你希望在vert.x項(xiàng)目里使用coroutine的話,建議使用vertx-sync。本篇將介紹vertx-sync。 showImg(/img/bVzIsu); 本來打算另起一篇,寫其他方面的東西,但是最近比較忙,就先寫一篇實(shí)...

    vpants 評(píng)論0 收藏0
  • Vert.x Blueprint 系列教程(三) | Micro-Shop 微服務(wù)應(yīng)用實(shí)戰(zhàn)

    摘要:本教程是藍(lán)圖系列的第三篇教程,對(duì)應(yīng)的版本為。提供了一個(gè)服務(wù)發(fā)現(xiàn)模塊用于發(fā)布和獲取服務(wù)記錄。前端此微服務(wù)的前端部分,目前已整合至組件中。監(jiān)視儀表板用于監(jiān)視微服務(wù)系統(tǒng)的狀態(tài)以及日志統(tǒng)計(jì)數(shù)據(jù)的查看。而服務(wù)則負(fù)責(zé)發(fā)布其它服務(wù)如服務(wù)或消息源并且部署。 本文章是 Vert.x 藍(lán)圖系列 的第三篇教程。全系列: Vert.x Blueprint 系列教程(一) | 待辦事項(xiàng)服務(wù)開發(fā)教程 Vert....

    QiShare 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<