HttpClient学习——1.基本操作

所有的Demo都在https://httpbin.org/上测试,这真是个了解Http协议的好网站,推荐一下。

1.1 Http请求

1.1.1 请求添加参数

get请求

/**
 * httpClient执行get请求
 */
@Test
public void getMethodDemo() throws IOException, URISyntaxException {

    URI uri = new URIBuilder()
            .setScheme("http")
            .setHost("www.httpbin.org")
            .setPath("get")
            .setParameter("test", "hello")
            .setParameter("q", "httpclient")
            .build();
    httpRequest = new HttpGet(uri);
}

如果执行post请求只需将HttpGet换成HttpPost即可

1.1.2 请求添加实体内容

Http协议中只有Post,Put和Patch三种方法支持实体内容的发送。

HttpClient中支持的实体内容种类有二十多种,常用的应该有以下几种:StringEntity, ByteArrayEntity,InputStreamEntity和 FileEntity

下面的Demo以Post方法发送StringEntity为例:

请求添加http实体
/**
 * httpClient通过post发送实体
 */
@Test
public void sendEntityDemo() throws IOException, URISyntaxException {

    URI uri = new URIBuilder()
            .setScheme("http")
            .setHost("www.httpbin.org")
            .setPath("post")
            .build();
    HttpPost httpPost = new HttpPost(uri);
    StringEntity stringEntity = new StringEntity("string entity");
    httpPost.setEntity(stringEntity);
    httpRequest = httpPost;
}

1.1.3 请求添加header

1.1.4 请求添加cookie

1.2 Http设置

HttpClient使用策略模式将Http设置封装为一组接口,这使我们能够选择性地用自定义这些设置,例如连接管理,状态管理,认证和重定向。

1.2.1 keep-alive设置

keep-alive设置

ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {

    @Override
    public long getKeepAliveDuration(
            HttpResponse response,
            HttpContext context) {
        long keepAlive = super.getKeepAliveDuration(response, context);
        if (keepAlive == -1) {
            // Keep connections alive 5 seconds if a keep-alive value
            // has not be explicitly set by the server
            keepAlive = 5000;
        }
        return keepAlive;
    }

};
CloseableHttpClient httpclient = HttpClients.custom()
        .setKeepAliveStrategy(keepAliveStrat)
        .build();

1.2.2 重定向设置

HttpClient自动为我们处理了重定向。下面是一个查看重定向URI的例子:

查看重定向URI

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("http://www.httpbin.org/redirect/6");
CloseableHttpResponse response = httpclient.execute(httpget, context);
try {
    HttpHost target = context.getTargetHost();
    List redirectLocations = context.getRedirectLocations();
    System.out.println(redirectLocations);
    URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations);
    System.out.println("Final HTTP location: " + location.toASCIIString());
} finally {
    response.close();
    httpclient.close();
}

发生重定向时之前传递的参数默认不会被传递到重定向的urI,这一点需要注意。

1.2.3 超时设置

通过RequestConfig类进行超时时间的设定:

超时设定

RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(1000)
        .setConnectTimeout(1000)
        .build();

HttpGet httpget = new HttpGet("http://localhost/1");
httpget.setConfig(requestConfig);

//还可以放在HttpClient的设置中将这个超时设置为默认配置
CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultRequestConfig(requestConfig)
    .build();
  • setConnectTimeout:建立连接超时时间,单位毫秒。默认-1,即无超时时间。
  • setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。默认-1,即无超时时间。
  • setSocketTimeout:请求获取数据的超时时间,单位毫秒。 可以理解为两个数据包之间最大的时间间隔。默认-1,即无超时时间。

1.2.4 代理设置

通过HttpClientBuilder#setRoutePlanner()方法或者RequestConfig.Builder#setProxy()可以设置代理,这里大家可以用自己的Http代理来试验下面的代码。

代理设置

HttpHost proxy = new HttpHost("proxy", port);
// 方法一:通过requestConfig设置代理
requestConfig = RequestConfig.custom()
        .setProxy(proxy)
        .build();
httpRequest.setRequestConfig(requestConfig);


// 方法二:通过setRoutePlanner设置全局代理
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
httpClient = HttpClients.custom()
        .setRoutePlanner(routePlanner)
        .build();

URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("www.httpbin.org")
        .setPath("get")
        .setParameter("test", "hello")
        .setParameter("q", "httpclient")
        .build();
httpRequest = new HttpGet(uri);

1.2.5 BA认证
1.2.6 重试设置
我们可以使用HttpRequestRetryHandler设置重试策略,处理当一些异常抛出的情况。

重试策略

HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

    public boolean retryRequest(
            IOException exception,
            int executionCount,
            HttpContext context) {
        if (executionCount >= 5) {
            // Do not retry if over max retry count
            return false;
        }
        if (exception instanceof InterruptedIOException) {
            // Timeout
            return false;
        }
        if (exception instanceof UnknownHostException) {
            // Unknown host
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {
            // Connection refused
            return false;
        }
        if (exception instanceof SSLException) {
            // SSL handshake exception
            return false;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(context);
        HttpRequest request = clientContext.getRequest();
        boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
        if (idempotent) {
            // Retry if the request is considered idempotent
            return true;
        }
        return false;
    }

};
CloseableHttpClient httpclient = HttpClients.custom()
        .setRetryHandler(myRetryHandler)
        .build();

1.3 Http返回结果处理

我们可以使用ResponseHandler接口来对Http返回结果做处理,这个接口有一个handleResponse方法,接收一个HttpResponse参数,返回一个T类型参数。
ResponseHandler

@After
public void requestWithResponseHandler() throws IOException {
    String responseStr = httpClient.execute(httpRequest, (response) ->IOUtils.toString(response.getEntity().getContent(), "utf-8"));
    System.out.println(responseStr);
}

在执行http请求时直接把responseHandler添加在HttpClient#executed的参数中,这样直接返回一个处理之后的对象。这样做的好处是HttpClient会自动关闭Entity#getContent()的流,详情可以看源码。

参考:httpclient官方文档

你可能感兴趣的:(Java)