首先获取代理, 并且判断是否代理打开
/** * 获取代理 * * @return */ private Map<String,Object> getProxy() { Map<String,Object> map = new HashMap<String,Object>(); HttpHost httphost = null; InputStream in = this.getClass().getClassLoader().getResourceAsStream("app-context.properties"); if (in != null) { Properties prop = new Properties(); try { prop.load(in); String proxy = ""; String proxyList = prop.getProperty("hcproxy.proxyList"); //在app-context.properties中设置的代理列表, 格式: proxyUrl:port/username:pwd if(null != proxyList && StringUtils.isNotBlank(proxyList)){ String[] proArr = proxyList.split(","); Random random = new Random(); int i = random.nextInt(proArr.length); //ip列表溢出问题 proxy = proArr[i]; if (!"".equals(proxy) && null != proxy) { logger.info("用于发送请求的代理ip:" + proxy); String[] array = proxy.split("/"); String host = array[0].split(":")[0]; String prot = array[0].split(":")[1]; httphost = new HttpHost(host, Integer.parseInt(prot)); if(array.length > 1){ String userAndPwd = array[1]; //用户名和密码 map.put("userAndPwd",userAndPwd); } map.put("httphost",httphost); } } } catch (IOException e) { logger.error("动态读取配置文件错误:" + e.getMessage(), e); } } return map; }
/** * 判断代理开关是否打开 * * @return */ private boolean isProxyOn() { boolean open = false; InputStream in = this.getClass().getClassLoader().getResourceAsStream("app-context.properties"); if (in != null) { Properties prop = new Properties(); try { prop.load(in); String isOn = prop.getProperty("isProxyOn"); if ("1".equals(isOn)) { open = true; } } catch (IOException e) { logger.error("动态读取配置文件错误:" + e.getMessage(), e); } } return open; }
一开始的时候并不需要用户名密码, 这样就可以获取返回数据
public CloseableHttpResponse post1(String url, List<NameValuePair> formparams) throws Exception { HttpPost httpPost = new HttpPost(url); httpPost.setHeader("x-requested-with", "XMLHttpRequest"); UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httpPost.setEntity(uefEntity); // 组装代理 if (isProxyOn()) { Map<String,Object> mapProxy = getProxy(); HttpHost proxy = (HttpHost) mapProxy.get("httphost"); if (null != proxy) { RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(30000) .setProxy(proxy).build(); httpPost.setConfig(requestConfig); } } CloseableHttpResponse HttpResponse = closeableHttpClient.execute(httpPost); return HttpResponse; }
但后来要使用了(目标地址需要, 逼不得已), 所以原来的方法不能用了
改成这样
public CloseableHttpResponse post(String url, Map<String, String> map) throws Exception { HttpPost httpPost = new HttpPost(url); if (map != null) { // 创建参数队列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); // 封装参数 for (Map.Entry<String, String> m : map.entrySet()) { formparams.add(new BasicNameValuePair(m.getKey(), m.getValue())); } UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); uefEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); httpPost.setEntity(uefEntity); } // 组装代理 if (isProxyOn()) { Map<String,Object> mapProxy = getProxy(); HttpHost proxy = (HttpHost) mapProxy.get("httphost"); if (null != proxy) { CredentialsProvider credsProvider = new BasicCredentialsProvider(); //要设置用户名密码的代理 if(null != mapProxy.get("userAndPwd")){ String username = ((String) mapProxy.get("userAndPwd")).split(":")[0]; String password = ((String) mapProxy.get("userAndPwd")).split(":")[1]; //创建认证,并设置认证范围 logger.info("代理用户名: " + username + " 密码: " + password); credsProvider.setCredentials(new AuthScope(proxy.getHostName(),proxy.getPort()), //可以访问的范围 new UsernamePasswordCredentials(username,password)); //用户名和密码 //重新创建client this.closeableHttpClient = HttpClientUtil.getIgnoreSslCertificateHttpClient(credsProvider); } RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(30000) .setProxy(proxy).build(); httpPost.setConfig(requestConfig); } } CloseableHttpResponse HttpResponse = closeableHttpClient.execute(httpPost); return HttpResponse; }
其中, 因为目标有证书验证, 所以需要忽略证书
//忽略证书 public static CloseableHttpClient getIgnoreSslCertificateHttpClient(CredentialsProvider credsProvider) throws HttpException { SSLContext sslContext = null; try { sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { return true; } }).build(); } catch (Exception e) { throw new HttpException("can not create http client.", e); } SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder .<ConnectionSocketFactory> create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory).build(); PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry); //keep alive 连接策略 ConnectionKeepAliveStrategy connectionKeepAliveStrategy = new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) { return 30 * 1000; // tomcat默认keepAliveTimeout为20s } }; connMgr.setMaxTotal(200); connMgr.setDefaultMaxPerRoute(200); // RequestConfig requestConfig = RequestConfig.custom() // .setConnectTimeout(10 * 1000) // .setSocketTimeout(10 * 1000) // .setConnectionRequestTimeout(10 * 1000) // .build(); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(30000).build(); return HttpClientBuilder.create() .setSslcontext(sslContext) .setConnectionManager(connMgr) .setDefaultRequestConfig(requestConfig) .setKeepAliveStrategy(connectionKeepAliveStrategy) .setDefaultCredentialsProvider(credsProvider) .build(); }还有些没写, 过后补上
另参考给代理ip设置用户名密码:
http://blog.youkuaiyun.com/zmx729618/article/details/54617053
http://bbs.youkuaiyun.com/topics/391844932?list=lz