httpClient4.3.3ABTH认证+密码访问
来源:互联网 发布:淘宝小号账号查询 编辑:程序博客网 时间:2024/06/03 21:31
这里,跟大家分享一个工具类。使用HTTPClient,访问需要密码的连接时,一般需要一个BATH认证。
package com.lzq;import java.io.IOException;import java.net.URI;import java.net.URISyntaxException;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.List;import java.util.concurrent.TimeUnit;import javax.net.ssl.SSLContext;import org.apache.commons.lang3.StringUtils;import org.apache.http.Header;import org.apache.http.HttpException;import org.apache.http.HttpHeaders;import org.apache.http.HttpHost;import org.apache.http.HttpRequest;import org.apache.http.HttpRequestInterceptor;import org.apache.http.HttpStatus;import org.apache.http.auth.AuthScheme;import org.apache.http.auth.AuthScope;import org.apache.http.auth.AuthState;import org.apache.http.auth.Credentials;import org.apache.http.auth.UsernamePasswordCredentials;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.CookieStore;import org.apache.http.client.CredentialsProvider;import org.apache.http.client.config.AuthSchemes;import org.apache.http.client.config.CookieSpecs;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.protocol.ClientContext;import org.apache.http.client.utils.URIBuilder;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.PlainConnectionSocketFactory;import org.apache.http.conn.ssl.AllowAllHostnameVerifier;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.conn.ssl.X509HostnameVerifier;import org.apache.http.impl.auth.BasicScheme;import org.apache.http.impl.client.BasicCookieStore;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.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.apache.http.message.BasicHeader;import org.apache.http.protocol.BasicHttpContext;import org.apache.http.protocol.ExecutionContext;import org.apache.http.protocol.HttpContext;import org.apache.http.util.EntityUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.lzq.monitor.utils.PropertiesFileUtil;import com.lzq.monitor.utils.https.DateFormatUtil;/** * httpClient 工具类 */@SuppressWarnings("deprecation")public class HttpClientUtils {/**HttpClient客户端连接管理器中,连接池最大连接数*/ public static final int HTTPCLIENT_CONN_MANAGER_MAXTOTAL = 1100;/**HttpClient客户端连接管理器中,连接池最大连接数*/public static final int HTTPCLIENT_CONN_MANAGER_MAXPERROUTE = 100;private static final Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);/**httpClient客户端*/private CloseableHttpClient httpClient = null;/**httpContext,可指定认证方式*/private BasicHttpContext localContext = null;/** ip */public static final String IP = "192.168.24.33"; /** 端口 */private static final int PORT = 438; public static void main(String[] args) {try {int intPort = 9696;URI uriDialing = new URIBuilder().setScheme("http").setHost(IP).setPort(PORT).setPath("/api/v1/port/"+intPort+"/redial").build();HttpClientUtils httpClientUtils = new HttpClientUtils();CloseableHttpResponse response =httpClientUtils.requestProcessorGet(uriDialing);String content = httpClientUtils.getContent(response);int intStatusCode = response.getStatusLine().getStatusCode(); //获取请求行if (intStatusCode != HttpStatus.SC_OK) { //如果不是200,则打印response的body信息logger.error(response.toString());}else {System.out.println(content);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 发送请求 * @param port * @return * @throws Exception */public CloseableHttpResponse requestProcessorGet(URI uri) throws Exception {List<Header> headers = this.getDefaultHeaders(null); //访问拨号接口的headersCloseableHttpResponse response = null; //访问拨号接口返回的responseCloseableHttpClient httpClient = null;try {httpClient = this.getHttpClient(uri.getHost(),uri.getPort());HttpGet httpGet = new HttpGet(uri); //拨号接口get请求// 设置请求头信息httpGet.setHeaders(headers.toArray(new Header[0]));response = httpClient.execute(httpGet,localContext);} catch (URISyntaxException e) {logger.error("uri异常", e);} catch (ClientProtocolException e) {logger.error("协议错误", e);} catch (IOException e) {logger.error("网络错误", e);} catch (Exception e) {logger.error("response未正常返回", e);}return response;}private CloseableHttpClient getHttpClient(String ip,int port) throws Exception{if (httpClient == null) {httpClient = this.proxyClientBuilder(ip,port);}return httpClient;}/** * 获取文本内容 * */public String getContent(CloseableHttpResponse resp) throws Exception {String content = null;try {content = EntityUtils.toString(resp.getEntity(),"gbk");EntityUtils.consume(resp.getEntity());} catch (Exception ex) {logger.error("获取内容失败", ex); } finally {if (resp != null) {resp.close();}}return content;}/** * 初始化代理客户端 * @throws Exception */private CloseableHttpClient proxyClientBuilder(String ip,int port) throws Exception {//http连接池PoolingHttpClientConnectionManager connManager = this.getHttpPoolManager();//userAnentString userAgent = "Mozilla/5.0 (Windows NT 6.1, WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36";//http请求的配置信息RequestConfig requestConfig = this.getReuestConfig(); //cookieCookieStore cookieStore = new BasicCookieStore();//远程被访问主机HttpHost targetHost = new HttpHost(ip, port, "http");CredentialsProvider credentialsProvider = this.getCredentialsProvider(targetHost); BasicScheme basicAuth = new BasicScheme();localContext = new BasicHttpContext();localContext.setAttribute("preemptive-auth", basicAuth);HttpClientBuilder httpClientBuilder = HttpClients.custom().setConnectionManager(connManager).setUserAgent(userAgent).setDefaultCookieStore(cookieStore).setDefaultRequestConfig(requestConfig).disableRedirectHandling();if (credentialsProvider!=null) {httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider).addInterceptorFirst(new PreemptiveAuthInterceptor()); // 此处连接器功能与credentialsProvider功能类似,二者可以选其一即可}CloseableHttpClient client = httpClientBuilder.build();return client;}/** * 获取主机信息 * @param targetHost * @return */private CredentialsProvider getCredentialsProvider(HttpHost targetHost) {String strUserName = "abc"; //http请求的用户名String strPassword = "pwd"; //http请求的密码CredentialsProvider credentialsProvider = null;AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort(),AuthScope.ANY_REALM);Credentials userNameCredentials = new UsernamePasswordCredentials(strUserName, strPassword);credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(authScope,userNameCredentials);logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<password="+userNameCredentials.getPassword()+";userName="+userNameCredentials.getUserPrincipal().getName());return credentialsProvider;}/** * http连接池 * @return * @throws Exception */private PoolingHttpClientConnectionManager getHttpPoolManager() throws Exception{Registry<ConnectionSocketFactory> registry = this.sslBuilder();PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry); //设置整个连接池最大连接数 根据自己的场景决定connManager.setMaxTotal(HTTPCLIENT_CONN_MANAGER_MAXTOTAL); // 将每个路由基础的连接增加 connManager.setDefaultMaxPerRoute(HTTPCLIENT_CONN_MANAGER_MAXPERROUTE); connManager.closeIdleConnections(0, TimeUnit.SECONDS); connManager.closeExpiredConnections();return connManager;}/** * httpClient连接配置信息 * @return */private RequestConfig getReuestConfig(){RequestConfig requestConfig = RequestConfig.custom() .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY) .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) .setSocketTimeout(20000) .setConnectTimeout(20000) .setConnectionRequestTimeout(20000) .setRedirectsEnabled(false) .build();return requestConfig;}/** * http连接器,请求发出前,进行拦截 */class PreemptiveAuthInterceptor implements HttpRequestInterceptor {@SuppressWarnings("deprecation")@Override public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); if (authState.getAuthScheme() == null) { AuthScheme authScheme = (AuthScheme) context.getAttribute("preemptive-auth"); if (authScheme != null) { CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER); HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); AuthScope authScope = new AuthScope(targetHost.getHostName(),targetHost.getPort(),AuthScope.ANY_REALM); Credentials creds = credsProvider.getCredentials(authScope); if (creds == null) { String strUserName = PropertiesFileUtil.MONITORINIT.getProperty("httpUserName"); //http请求的用户名 String strPassword = PropertiesFileUtil.MONITORINIT.getProperty("httpPassword"); //http请求的密码 if (StringUtils.isBlank(strUserName) && StringUtils.isBlank(strPassword)) { logger.info("配置文件中并没有取到:ADSL拨号的用户名、密码"+DateFormatUtil.formatDate(new Date())); } Credentials userNameCredentials = new UsernamePasswordCredentials(strUserName, strPassword); authState.setCredentials(userNameCredentials);// throw new HttpException("No credentials for preemptive authentication"); }else { authState.setCredentials(creds); logger.info("<<<<<<<<<<<<<<<<<<<<<<认证信息,拦截器截到不为空!!!!"+DateFormatUtil.formatDate(new Date()));} authState.setAuthScheme(authScheme); } } }}/** * 获取固定的请求header * */public List<Header> getDefaultHeaders(String referer) {List<Header> headers = new ArrayList<Header>();headers.add(new BasicHeader(HttpHeaders.ACCEPT,"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"));headers.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br"));headers.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE,"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"));if (StringUtils.isNotBlank(referer)) {headers.add(new BasicHeader(HttpHeaders.REFERER, referer));}return headers;}/** * 销毁httpClient * @throws Exception */public void destroyHttpClient() {try {if (httpClient != null) {httpClient.close();httpClient = null;}} catch (Exception e) {e.printStackTrace();}}/** * 构建SSLContext * 1.支持https访问 * 2.支持https双向证书验证 */protected Registry<ConnectionSocketFactory> sslBuilder() throws Exception {SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build();X509HostnameVerifier hostnameVerifier = new AllowAllHostnameVerifier();Registry<ConnectionSocketFactory> socketFactoryRegistry = null;socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https",new SSLConnectionSocketFactory(sslContext,hostnameVerifier)).build();return socketFactoryRegistry;}}
HttpClient,源代码中,第一次访问时,默认并不带上BATH认证信息,而是走普通的Http请求,访问失败后,HttpClient有重试机制,它会去匹配,最相近的访问方式,然后匹配到BATH认证方式之后,再带上BATH信息访问链接。
这种方式实现也可以达到目的,不过我们可以通知强制HttpClient使用BATH认证进行访问,那么每一次访问,就不需要多一次Http请求了。
HttpClient的使用,还是有一些坑的,不过也给我们提供了更大的便利。这就需要我们根据自己的需要去完善它。
1 0
- httpClient4.3.3ABTH认证+密码访问
- HttpClient4基础2--通过认证代理访问网页
- HttpClient4基础2--通过认证代理访问网页
- HttpClient4基础2--通过认证代理访问网页
- HttpClient4基础2--通过认证代理访问网页
- 利用httpclient4.3.1,用户名,密码,访问远程数据。
- redis配置认证密码以及远程访问
- httpclient4.x访问https
- nginx实现访问网站或目录密码认证保护
- nginx让用户通过用户名密码认证访问web页面
- HttpClient4.5 get访问实例
- HttpClient4.3教程 第四章 HTTP认证
- HttpClient4.3教程 第四章 HTTP认证
- httpclient4.4 http摘要认证请求
- HttpClient4.3.3 https请求
- httpclient3与httpclient4访问的一些区别
- HttpClient4.x调用指定证书访问https
- HttpClient4.5 SSL访问工具类
- java.lang.IllegalStateException: No output folder
- matlab查找集合中某个元素的位置/Struct结构体某个字段值的位置
- POJ3579--Median(二分)
- 用JavaScript做一个简单的框选图表
- Android从相册选取视频(单一)
- httpClient4.3.3ABTH认证+密码访问
- cocos-code-ide新建项目不动卡死的问题
- 我与python约个会:05第一个python程序
- php页面调用微信扫一扫
- 顶部标题栏自定义
- leetcode题解c++ | 72. Edit Distance
- 【转载】一个三年程序员应该掌握的技能
- Mini2440学习日记(2)_U-boot的启动流程分析
- VS2010每次编译都重新编译整个工程的解决方案