WebClient发送Web请求(post && get)

1.参考

1.Spring WebClient 教程

2.Netty客户端-配置DNSResolution超时

2.创建WebClient

/**
 * 创建 webclient实例
 * @return webclient实例
 */
 public WebClient buildWebClient(){
   return WebClient.builder()
      .clientConnector(new ReactorClientHttpConnector(buildHttpClient()))
      .build();
}


/**
     * 创建 http client 实例
     *
     * 通过 ChannelOption.CONNECT_TIMEOUT_MILLIS 选项设置连接超时间。
     * 分别使用 ReadTimeoutHandler 和写 WriteTimeoutHandler 设置读、写超时。
     * 使用 responseTimeout 指令配置响应超时。
     *
     * @return HttpClient
     */
    private HttpClient buildHttpClient() {
        try{
            SslContext sslContext = SslContextBuilder
                    .forClient()
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .build();

            return HttpClient.create()
                    // 忽略https 安全证书检查 可选项
                    .secure(t -> t.sslContext(sslContext))
                    // 设置DNS查询超时时间 解决 io.netty.resolver.dns.DnsNameResolverTimeoutException
                    .resolver(spec -> spec.queryTimeout(Duration.ofSeconds(20)))
                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30 * 1000)
                    .responseTimeout(Duration.ofMillis(30 * 1000L))
                    .doOnConnected(conn ->
                            conn.addHandlerLast(new ReadTimeoutHandler(30 * 1000L, TimeUnit.MILLISECONDS))
                                    .addHandlerLast(new WriteTimeoutHandler(30 * 1000L, TimeUnit.MILLISECONDS)));
        }catch (SSLException e){
            log.error("创建HttpClient出错{}", e.getMessage());
            throw exception(CREATE_HTTP_CLIENT_FAIL);
        }

    }

3.发送post与get请求

public String getWeb(){

        String res =  buildWebClient()
                .get()
                .uri( 请求的地址(http://localhost:12345/api/get),
                        // 构造query参数
                        uriBuilder -> uriBuilder
                                .queryParam("参数名1", "值1")
                                .queryParam("参数名2", "值2")
                                .build()
                        )
                // 请求头
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeToMono(response -> response.bodyToMono(String.class))
                .block();
        return res;
    }
public String postWeb(){

        String res =  buildWebClient()
                .post()
                .uri( 请求的地址(http://localhost:12345/api/get))
                // 请求头
                .bodyValue(body参数)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .exchangeToMono(response -> response.bodyToMono(String.class))
                .block();
        return res;
    }

在获取响应中,.exchangeToMono(response -> response.bodyToMono(String.class))可以有更加详细的写法

.exchangeToMono(response -> {
  if (response.statusCode().equals(HttpStatus.OK)) {
      return response.bodyToMono(String.class);
  } else if (response.statusCode().is4xxClientError()) {
      return Mono.just("Error response");
  } else {
      return response.createException()
        .flatMap(Mono::error);
  }
});

4.个人遇到的问题

1.io.netty.resolver.dns.DnsNameResolverTimeoutException异常

在发送http请求时,不是直接的ip,需要DNS解析,我在发送请求的时候,总是报DNS解析超时。解决办法就是创建httpClient时,延长DNS查询时间。

.resolver(spec -> spec.queryTimeout(Duration.ofSeconds(20)))

2.响应解析

因为获取的响应是String形式的,如何把String解析成想要获取的信息了,个人的做法是通过JSONObject和JSON.parseArray解析。

/**
     * 解析返回 并封装
     * @param response 返回
     * @return 封装后的响应
     */
    private BaseResponse<String> parseResponse(String response){
        try {
            JSONObject json = JsonUtils.parseObject(response);
            // code 为200 表明成功
            int code = json.get("code", Integer.class);
            if (code == HttpStatus.OK.value()) {
                String data = json.get("result", String.class);
                return BaseResponse.success(data);
            } else {
                log.error("接口访问失败{}", response);
                return BaseResponse.fail(code, json.getStr("message"));
            }
        }catch (Exception e){
            log.error("解析{}响应出错,{}", response, e.getMessage());
            return BaseResponse.fail(e.getMessage());
        }
    }

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值