Http请求实践

作者: yangc91 | 来源:发表于2018-06-22 14:19 被阅读2次

后台开发时,经常需要进行系统对接,远程接口调用非常普遍,现总结一下针对http接口的远程调用

常用工具:

  • HttpClient(4.3.3)
  • OKHttp(3.10.0)

HttpClient

构建全局公用的httpclient连接池

public class HttpClientPoolUtil {

  private static Integer POOL_MAX_TOTAL = 300;
  private static Integer POOL_DEFAULT_MAX_PERROUTE = 200;

  private static CloseableHttpClient httpclient = null;

  /**
   * 全局公用一个httpclient连接池
   * https暂只支持单向认证
   */
  public static synchronized CloseableHttpClient getHttpClient() {

    if (null == httpclient) {
      // https相关设置, 只支持单向认证
      SSLContext sslcontext = null;
      try {
        sslcontext = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustStrategy() {
              @Override
              public boolean isTrusted(X509Certificate[] chain, String authType) {
                // 允许自签名证书
                return true;
              }
            }).build();
      } catch (Exception e) {
        e.printStackTrace();
      }

      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
          sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

      // SSLConnectionSocketFactory.getSystemSocketFactory();
      // 注册访问协议的相关工厂
      Registry<ConnectionSocketFactory> socketFactoryRegistry =
          RegistryBuilder.<ConnectionSocketFactory>create()
              .register("http", PlainConnectionSocketFactory.INSTANCE)
              .register("https", sslsf)
              .build();

      HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory =
          new ManagedHttpClientConnectionFactory(
              DefaultHttpRequestWriterFactory.INSTANCE, DefaultHttpResponseParserFactory.INSTANCE);

      DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;

      // Create a connection manager with custom configuration.
      PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
          socketFactoryRegistry, connFactory, dnsResolver);

      // Create socket configuration
      SocketConfig socketConfig = SocketConfig.custom()
          .setTcpNoDelay(true)
          .build();

      connManager.setDefaultSocketConfig(socketConfig);
      // 连接池最大连接数
      connManager.setMaxTotal(POOL_MAX_TOTAL);
      // 每个路由默认的最大连接数
      connManager.setDefaultMaxPerRoute(POOL_DEFAULT_MAX_PERROUTE);
      // 对单个域名的路由设置最大连接数
      //connManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20)

      // Create global request configuration
      RequestConfig requestConfig = RequestConfig.custom()
          .setConnectTimeout(2000) // 连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
          .setSocketTimeout(5000) // 服务器返回数据(response)的时间
          .setConnectionRequestTimeout(2000) // 从连接池中获取连接的超时时间,超过该时间未拿到可用连接
          .build();

      httpclient = HttpClients.custom()
          .setConnectionManager(connManager)
          .setDefaultRequestConfig(requestConfig)
          .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
          .build();

      // JVM 停止或重启时,关闭连接池释放连接
      Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
          try {
            httpclient.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      });
    }
    return httpclient;
  }
}

GET请求

HttpGet httpGet = new HttpGet("http://targethost/homepage");
    CloseableHttpResponse response1 = HttpClientPoolUtil.getHttpClient().execute(httpGet);

    int statusCode = response1.getStatusLine().getStatusCode();
    if (statusCode != HttpStatus.SC_OK) {
      EntityUtils.consume(response1.getEntity());
    } else {
      // do something useful with the response body
      String result = EntityUtils.toString(response1.getEntity(), "utf-8");
    }

POST请求

HttpPost httpPost = new HttpPost("http://targethost/login");
    List<NameValuePair> nvps = new ArrayList<>();
    nvps.add(new BasicNameValuePair("username", "vip"));
    nvps.add(new BasicNameValuePair("password", "secret"));
    //httpPost.addHeader("", "");

    // json请求
    StringEntity entity = new StringEntity(Json.toJson(nvps), ContentType.APPLICATION_JSON);
    httpPost.setEntity(entity);

    // form请求
    // httpPost.setEntity(new UrlEncodedFormEntity(nvps));

    CloseableHttpResponse response2 = httpclient.execute(httpPost);

    statusCode = response2.getStatusLine().getStatusCode();
    if (statusCode != HttpStatus.SC_OK) {
      EntityUtils.consume(response2.getEntity());
    } else {
      // do something useful with the response body
      String result = EntityUtils.toString(response2.getEntity(), "utf-8");
    }

OKHttp

GET请求

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
  .url(url)
  .build();

try (Response response = client.newCall(request).execute()) {
  return response.body().string();
}

POST请求

OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();
try (Response response = client.newCall(request).execute()) {
  return response.body().string();
}

参考资料

相关文章

  • Http请求实践

    后台开发时,经常需要进行系统对接,远程接口调用非常普遍,现总结一下针对http接口的远程调用 常用工具: Http...

  • Android 发送 HTTP 请求最佳实践

    发送 HTTP 请求的方法其实都有一套固定的模板,所以我们可以把这些方法整合到一个工具类中。 这样做粗看起来似乎可...

  • OkHttp之Call

    HTTP客户端的职责是接收请求产出响应,理论上简单但实践中却棘手。 Request 每个HTTP请求包含一个URL...

  • 【HTTP】HTTP请求

    1、HTTP协议通信流程: 2、HTTP请求包含内容 一个HTTP请求报文由请求行(request line)、请...

  • 【接口/性能】python03-根据接口文档发送HTTP请求

    实践:根据接口文档发送HTTP请求 一、需先了解公共的基础请求信息协议文档 包括以下信息: 1. info:即平台...

  • 动脑学院架构篇-HTTP请求、响应报文格式

    【HTTP】HTTP请求、响应报文格式 HTTP请求报文格式: HTTP请求报文主要由请求行、请求头部、请求数据3...

  • IDEA自带http请求工具

    编辑http请求文件(文件名后缀为.http) GET请求 POST请求 执行http请求 查看http结果

  • HTTP

    HTTP简介 HTTP请求格式 HTTP规定,HTTP请求由如下3部分构成 请求方法、URI和HTTP的版本 请求...

  • HTTP协议报文及Chrome Network常用功能

    HTTP协议报文 Http协议报文分为【Http请求报文】和【Http响应报文】 HTTP请求报文 Http请求报...

  • HTTP 请求

    Code=-999 错误400 ------参数错误网络请求出现Code=-1022

网友评论

    本文标题:Http请求实践

    本文链接:https://www.haomeiwen.com/subject/eyykyftx.html