zoukankan      html  css  js  c++  java
  • Vert.x WebClient WebClientOptions

    本文参考自Vert.x Web Client官方文档。套用官网的话来说,

    Vert.x Web Client是一个异步的HTTP和HTTP/2网络客户端。

    相对来说,这是一个比较小的框架,而且功能也很直接,做一个方便好用的HTTP客户端。它具有以下功能:

    Json body 编码 / 解码
    request 参数
    统一的错误处理
    表单提交
    需要注意,它和Vertx核心包中的HttpClient有很多联系。它继承了HttpClient,提供了更多功能。

    引用类库
    要使用这个类库很简单。如果使用Maven,添加下面的依赖。

    <dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web-client</artifactId>
    <version>3.4.2</version>
    </dependency>
     
    如果使用Gradle,添加下面的依赖。

    dependencies {
    compile 'io.vertx:vertx-web-client:3.4.2'
    }
     
    创建客户端
    创建客户端稍微有点不一样。

    WebClient client = WebClient.create(vertx);
     
    如果要添加配置参数,可以这样做。

    WebClientOptions options = new WebClientOptions()
    .setUserAgent("My-App/1.2.3");
    options.setKeepAlive(false);
    WebClient client = WebClient.create(vertx, options);
     
    如果已经有了HttpClient,可以重用它。

    WebClient client = WebClient.wrap(httpClient); 
    发起请求
    无请求体的请求
    这是最简单的情况,一般的GET、HEAD等请求都输这种方式。

    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());
    }
    });
     
    如果要携带查询参数,可以采用流式API。

    client
    .get(8080, "myserver.mycompany.com", "/some-uri")
    .addQueryParam("param", "param_value")
    .send(ar -> {});
     
    也可以直接在URL中设置查询参数。

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

    // 添加参数1
    request.addQueryParam("param1", "param1_value");

    // 用URL覆盖参数
    request.uri("/some-uri?param1=param1_value&param2=param2_value");
     
    添加请求体
    假如使用POST方式传递参数,或者上传图片等,就需要带有请求体的请求了。这种情况下,只需要额外使用sendXXX等方法添加要传递的请求体即可。

    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());
    }
    });
     
    如果要发送的信息比较大,可以使用sendStream方法,使用流来传输数据。

    client
    .post(8080, "myserver.mycompany.com", "/some-uri")
    .sendStream(stream, resp -> {});
     
    Json请求体
    有时候可能需要发送Json数据,这时候可以使用sendJsonObject方法。

    client
    .post(8080, "myserver.mycompany.com", "/some-uri")
    .sendJsonObject(new JsonObject()
    .put("firstName", "Dale")
    .put("lastName", "Cooper"), ar -> {
    if (ar.succeeded()) {
    // Ok
    }
    });
     
    发送表单
    发送表单使用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());
    }
    });
     
    默认表单使用application/x-www-form-urlencoded类型的Content Type发送,也可以修改成multipart/form-data类型。

    client
    .post(8080, "myserver.mycompany.com", "/some-uri")
    .putHeader("content-type", "multipart/form-data")
    .sendForm(form, ar -> {
    if (ar.succeeded()) {
    // Ok
    }
    });
     
    目前上传文件还不支持,将会在以后的版本中支持上传文件。

    修改请求头
    可以添加和修改要发送的请求头。

    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");
     
    也可以调用putHeader方法直接添加请求头。

    HttpRequest<Buffer> request = client.get(8080, "myserver.mycompany.com", "/some-uri");
    request.putHeader("content-type", "application/json");
    request.putHeader("other-header", "foo");
     
    重用请求
    如果需要对同一个地址发起多次请求,我们可以设置一次请求,然后重复使用它。

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

    // 重复使用
    get.send(ar -> {
    if (ar.succeeded()) {
    // Ok
    }
    });
      
    超时
    发起请求的时候可以设置超时值,单位是毫秒。

    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
    }
    });
     
    处理请求
    处理请求也是异步的。这里的ar类型实际是AsyncResult的类型,代表异步结果。如果结果成功了,调用result()方法返回HttpResponse<Buffer>类型对象,这就是我们发起请求的结果,调用statusCode()、body()等方法就可以查看相应结果了。

    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());
    }
    });
     
    解码响应
    前面的响应是以Buffer形式返回的。如果我们确定响应是普通字符串、Json对象、可以和Json映射的POJO类以及WriteStream,我们还可以解码响应。例如下面就将响应体解码为了JsonObject对象。

    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类还有另外几个方法,可以将响应体解码为不同类型。假如响应体比较大,可以直接将响应体转换为输出流,以后慢慢读取。

    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());
    }
    });
     
    如果确定不需要响应体,可以直接用none()方法扔掉响应体。

    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());
    }
    });
     
    当然,如果响应体还是解码为Buffer,我们仍然可以调用bodyAsXXX方法来解码响应体。这种方法仅适用于Buffer响应体。

    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连接也很容易,将端口号指定为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());
    }
    }); 
    或者使用绝对路径标志的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());
    }
    });  

  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/endv/p/12601902.html
Copyright © 2011-2022 走看看