apache httpclient 4 范例
阅读原文时间:2023年07月10日阅读:1

下面是一个通过apache httpclient 4 实现http/https的普通访问和BasicAuth认证访问的例子。依赖的第三方库为:

下面是具体实现:

package test;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;

/**
* HttpClient的包装类,支持http/https的普通访问和basic Auth认证访问
* @author needle
*
*/
public class HttpUtilDemo {
//默认超时时间
private static final int DEFAULT_TIMEOUT = 5000;

public static class HttpResult{  
    public final int STATUS;  
    public String CONTENT;

    public HttpResult(int status, String content){  
        this.STATUS = status;  
        this.CONTENT = content;  
    }  
}

private static void setTimeout(HttpRequestBase post) {  
    RequestConfig requestConfig = RequestConfig.custom()  
            .setConnectTimeout(DEFAULT\_TIMEOUT).setConnectionRequestTimeout(DEFAULT\_TIMEOUT)  
            .setSocketTimeout(DEFAULT\_TIMEOUT).build(); 

    post.setConfig(requestConfig);  
}

//这里是同时支持http/https的关键  
private static CloseableHttpClient getHttpClient(HttpClientBuilder httpClientBuilder) {  
    RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();  
    ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();  
    registryBuilder.register("http", plainSF);  
    //指定信任密钥存储对象和连接套接字工厂  
    try {  
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());  
        //信任任何链接  
        TrustStrategy anyTrustStrategy = new TrustStrategy() {  
            @Override  
            public boolean isTrusted(X509Certificate\[\] x509Certificates, String s) throws CertificateException {  
                return true;  
            }  
        };  
        SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, anyTrustStrategy).build();  
        LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW\_ALL\_HOSTNAME\_VERIFIER);  
        registryBuilder.register("https", sslSF);  
    } catch (KeyStoreException e) {  
        throw new RuntimeException(e);  
    } catch (KeyManagementException e) {  
        throw new RuntimeException(e);  
    } catch (NoSuchAlgorithmException e) {  
        throw new RuntimeException(e);  
    }  
    Registry<ConnectionSocketFactory> registry = registryBuilder.build();  
    //设置连接管理器  
    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry); 

    //构建客户端  
    return httpClientBuilder.setConnectionManager(connManager).build();  
}  

//获取普通访问的HttpClient  
private static CloseableHttpClient getHttpClient() {  
    return getHttpClient(HttpClientBuilder.create());  
}

//获取支持basic Auth认证的HttpClient  
private static CloseableHttpClient getHttpClientWithBasicAuth(String username, String password){  
    return getHttpClient(credential(username, password));  
}

//配置basic Auth 认证  
private static HttpClientBuilder credential(String username, String password) {  
    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();  
    CredentialsProvider provider = new BasicCredentialsProvider();  
    AuthScope scope = new AuthScope(AuthScope.ANY\_HOST, AuthScope.ANY\_PORT, AuthScope.ANY\_REALM);  
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);  
    provider.setCredentials(scope, credentials);  
    httpClientBuilder.setDefaultCredentialsProvider(provider);  
    return httpClientBuilder;  
}

//设置头信息,e.g. content-type 等  
private static void setHeaders(HttpRequestBase req, Map<String, String> headers){  
    if(headers == null) return;

    for(Entry<String, String> header : headers.entrySet()){  
        req.setHeader(header.getKey(), header.getValue());  
    }  
}

/\*\*  
 \* get基础类,支持普通访问和Basic Auth认证  
 \* @param uri  
 \* @param headers  
 \* @param client 不同的方式不同的HttpClient  
 \* @param isTimeout 是否超时  
 \* @return  
 \*/  
private static HttpResult get(String uri, Map<String, String> headers, CloseableHttpClient client, boolean isTimeout){  
    try(CloseableHttpClient httpClient = client){

        HttpGet get = new HttpGet(uri);  
        setHeaders(get, headers);

        if(isTimeout){  
            setTimeout(get);  
        }

        try(CloseableHttpResponse httpResponse = httpClient.execute(get)){  
            int status = httpResponse.getStatusLine().getStatusCode();  
            if(status != HttpStatus.SC\_NOT\_FOUND){  
                return new HttpResult(status, IOUtils.toString(httpResponse.getEntity().getContent(), "utf-8"));  
            }else{  
                return new HttpResult(status, "404");  
            }  
        }  
    } catch (IOException e) {  
        throw new RuntimeException(e);  
    }  
}

public static HttpResult get(String uri, Map<String, String> headers, boolean isTimeout){  
    return get(uri, headers, getHttpClient(), isTimeout);  
}

public static HttpResult getWithBaiscAuth(String uri, Map<String, String> headers, String username, String password, boolean isTimeout){  
    return get(uri, headers, getHttpClientWithBasicAuth(username, password), isTimeout);  
}

public static HttpEntity createUrlEncodedFormEntity(Map<String, String> params){  
    List<NameValuePair> data = new ArrayList<>();  
    for(Map.Entry<String, String> entry : params.entrySet()){  
        data.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));  
    }  
    try {  
        return new UrlEncodedFormEntity(data, "UTF-8");  
    } catch (UnsupportedEncodingException e) {  
        throw new RuntimeException(e);  
    }  
}

public static HttpEntity createStringEntity(String body){  
    try {  
        return  new StringEntity(body);  
    } catch (UnsupportedEncodingException e) {  
        throw new RuntimeException(e);  
    }  
}

private static HttpResult post(CloseableHttpClient client, String uri, Map<String, String> headers, HttpEntity entity, boolean isTimeout){  
    try(CloseableHttpClient httpClient = client){  
        HttpPost post = new HttpPost(uri);  
        setHeaders(post, headers);  
        if(isTimeout){  
            setTimeout(post);  
        }  
        post.setEntity(entity);  
        try(CloseableHttpResponse httpResponse = httpClient.execute(post)){  
            int status = httpResponse.getStatusLine().getStatusCode();

            if(status != HttpStatus.SC\_NOT\_FOUND){  
                return new HttpResult(status, IOUtils.toString(httpResponse.getEntity().getContent(), "utf-8"));  
            }else{  
                return new HttpResult(status, "404");  
            }  
        }  
    } catch (IOException e) {  
        throw new RuntimeException(e);  
    }  
}

public static HttpResult post(String uri, Map<String, String> headers, HttpEntity entity, boolean isTimeout){  
    return post(getHttpClient(), uri,headers, entity, isTimeout);  
}

public static HttpResult postWithBasicAuth(String uri, Map<String, String> headers, String username, String password, HttpEntity entity, boolean isTimeout){  
    return post(getHttpClientWithBasicAuth(username, password), uri, headers,  entity, isTimeout);  
}

public static void main(String\[\] args) throws UnsupportedEncodingException {  
    Map<String, String> headers = new HashMap<String, String>();  
    headers.put("isClient","true");  
    headers.put("content-type", "application/xml");  
    headers.put("content-encoding", "UTF-8");

    String body = "<action><status></status><fault><reason></reason><detail></detail></fault></action>";

    //测试操作Ovirt 虚拟机  
    HttpResult result = postWithBasicAuth("https://192.168.104.71/api/vms/41feaa71-4cb9-4c22-9380-ee530143eb0d/stop", headers, "sysadmin@internal", "admin==1", new StringEntity(body), false);

    System.out.println(result.STATUS);  
    System.out.println(result.CONTENT);  
}  

}