下面是一个通过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); } }