废话不多说,直接上代码
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
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.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.SchemePortResolver;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.routing.HttpRoutePlanner;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultRoutePlanner;
import org.apache.http.impl.conn.DefaultSchemePortResolver;
import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SystemDefaultDnsResolver;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
/**
* HTTP连接工具类
* 基于 HttpComponents 实现,需要依赖以下JAR文件: httpclient-4.5.jar/httpcore-4.4.1.jar/httpmime-4.5.jar/commons-logging-1.1.1.jar
*
*/
public class KHttpTools {
/************* httpclient 连接池 ******************/
private static HttpRoutePlanner RoutePlanner = null;
private static HttpClientConnectionManager ConnManager = null;
private static final int DefaultConnMaxTotal = 1000;
private static final int DefaultConnMaxPerRoute = 1000;
private static void initConnectionManager(){
//构建http连接管理对象(PoolingHttpClientConnectionManager)
SSLContext sslContext = null;
{
try{
sslContext = SSLContext.getInstance("SSL","SunJSSE");
X509TrustManager mytm = new X509TrustManager() {
//忽略证书检查
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] chain,
String authType)
throws java.security.cert.CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws java.security.cert.CertificateException {
}
};
TrustManager[] tm = { mytm };
sslContext.init(null, tm, new java.security.SecureRandom());
}catch(Exception e){
}
}
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", sslsf).build();
ConnManager = new PoolingHttpClientConnectionManager( socketFactoryRegistry,
ManagedHttpClientConnectionFactory.INSTANCE,
DefaultSchemePortResolver.INSTANCE,
SystemDefaultDnsResolver.INSTANCE,
-1, TimeUnit.MILLISECONDS);
((PoolingHttpClientConnectionManager)ConnManager).setMaxTotal(DefaultConnMaxTotal);
((PoolingHttpClientConnectionManager)ConnManager).setDefaultMaxPerRoute(DefaultConnMaxPerRoute);
//发起后台线程:定期回收已过期的连接对象
Thread thread = new Thread(new Runnable(){
public void run(){
try {
while (true) {
synchronized (this) {
Thread.sleep(5000);
// 关闭失效的连接
ConnManager.closeExpiredConnections();
// 可选的, 关闭30秒内不活动的连接
ConnManager.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
// terminate
}
}
});
thread.setName("KABALA_HttpclientRelease");
thread.setDaemon(true);
thread.start();
}
public static HttpClientConnectionManager getConnectionManager(){
if(ConnManager==null){
initConnectionManager();
}
return ConnManager;
}
public static void setConnectionManager(HttpClientConnectionManager cm){
if(cm!=null){
ConnManager = cm;
}
}
public static void setRoutePlanner(HttpRoutePlanner routePlanner){
RoutePlanner = routePlanner;
}
public static HttpRoutePlanner getRoutePlanner(){
return RoutePlanner;
}
public static HttpRoutePlanner createMapperRoutePlanner(final Map routemap){
return new MyRoutePlanner(DefaultSchemePortResolver.INSTANCE, routemap);
}
static class MyRoutePlanner extends DefaultRoutePlanner{
private final Map m_routemap;
public MyRoutePlanner(final SchemePortResolver schemePortResolver, Map routemap) {
super(schemePortResolver);
m_routemap = new HashMap();
m_routemap.putAll(routemap);
}
@Override
public HttpRoute determineRoute(
final HttpHost host,
final HttpRequest request,
final HttpContext context) throws HttpException {
HttpRoute route = super.determineRoute(host, request, context);
if(m_routemap!=null && m_routemap.size()>0){
HttpHost targethost = route.getTargetHost();
HttpHost newTargethost = tryRedirectHost(targethost);
if(newTargethost==null){
return route;
}else{
if(route.getProxyHost()==null)
return new HttpRoute(newTargethost, route.getLocalAddress(), route.isSecure());
else
return new HttpRoute(newTargethost, route.getLocalAddress(), route.getProxyHost(), route.isSecure());
}
}else{
return route;
}
}
private HttpHost tryRedirectHost(HttpHost host){
String addr = host.getSchemeName()+"://"+host.getHostName();
if( ("http".equals(host.getSchemeName()) && 80==host.getPort()) || ("https".equals(host.getSchemeName()) && 443==host.getPort()) ){
}else{
addr += ":"+String.valueOf(host.getPort());
}
if(m_routemap.containsKey(addr)){
String redirectAddr = String.valueOf(m_routemap.get(addr));
if(redirectAddr!=null && redirectAddr.length()>0){
//需要跳转:
try{
return HttpHost.create(redirectAddr);
}catch(Exception e){
return null;
}
}
}
//无需跳转
return null;
}
}
//申请一个 CloseableHttpClient 连接对象
private static CloseableHttpClient getHttpClient(String url, final int connect_timeout, final int read_timeout){
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connect_timeout).setSocketTimeout(read_timeout).build();
CloseableHttpClient httpclient = HttpClients.custom().setRoutePlanner(getRoutePlanner())
.setConnectionManager(getConnectionManager())
.setDefaultRequestConfig(requestConfig)
.build();
return httpclient;
}
//返回结果对象接口:
public static class KHttpResponse {
private final int m_statuscode;
private final String m_response;
public KHttpResponse(int code, String response){
m_statuscode = code;
m_response = response;
}
//获取返回状态
public int getResponseCode(){
return m_statuscode;
}
//消费返回数据流--字符串格式
public String getResponseString(){
return m_response;
}
}
//执行请求:
public static KHttpResponse doGet(final String urladdr, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
HttpGet req = new HttpGet(urladdr);
return request(req, headers, connect_timeout, read_timeout);
}
//post方式传递参数
public static KHttpResponse doPost(final String urladdr, final Map headers, final Map params, final int connect_timeout, final int read_timeout) throws IOException{
HttpPost req = new HttpPost(urladdr);
UrlEncodedFormEntity httpentity = null;
if(params!=null){
List<NameValuePair> parampairs = new ArrayList<NameValuePair>();
Iterator iter = params.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String)entry.getKey();
String value = "";
if(entry.getValue()!=null){
value = String.valueOf(entry.getValue());
}
parampairs.add(new BasicNameValuePair(key, value));
}
httpentity = new UrlEncodedFormEntity(parampairs, "utf-8");
req.setEntity(httpentity);
}
return request(req, headers, connect_timeout, read_timeout);
}
//post方式传递request-body
public static KHttpResponse doPostBody(final String urladdr, final Map headers, final byte[] reqBody, final int connect_timeout, final int read_timeout) throws IOException{
HttpPost req = new HttpPost(urladdr);
if(reqBody!=null){
ByteArrayEntity entity = new ByteArrayEntity(reqBody);
req.setEntity(entity);
}
return request(req, headers, connect_timeout, read_timeout);
}
//put方式如需传递参数,请将参数放在urladdr中拼接
public static KHttpResponse doPut(final String urladdr, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
HttpPut put = new HttpPut(urladdr);
return request(put, headers, connect_timeout, read_timeout);
}
//put方式传递request-body
public static KHttpResponse doPutBody(final String urladdr, final Map headers, final InputStream bodyStream, final long bodySize, final int connect_timeout, final int read_timeout) throws IOException{
HttpPut put = new HttpPut(urladdr);
put.setEntity(new InputStreamEntity(bodyStream, bodySize));
return request(put, headers, connect_timeout, read_timeout);
}
public static KHttpResponse doPutBody(final String urladdr, final Map headers, final byte[] reqBody, final int connect_timeout, final int read_timeout) throws IOException{
HttpPut put = new HttpPut(urladdr);
if(reqBody!=null){
ByteArrayEntity entity = new ByteArrayEntity(reqBody);
put.setEntity(entity);
}
return request(put, headers, connect_timeout, read_timeout);
}
public static KHttpResponse doDelete(final String urladdr, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
HttpDelete req = new HttpDelete(urladdr);
return request(req, headers, connect_timeout, read_timeout);
}
public static KHttpResponse doHead(final String urladdr, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
HttpHead req = new HttpHead(urladdr);
return request(req, headers, connect_timeout, read_timeout);
}
public static KHttpResponse doOptions(final String urladdr, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
HttpOptions req = new HttpOptions(urladdr);
return request(req, headers, connect_timeout, read_timeout);
}
static KHttpResponse request(HttpUriRequest httpreq, final Map headers, final int connect_timeout, final int read_timeout) throws IOException{
CloseableHttpClient httpclient = getHttpClient(httpreq.getURI().toString(), connect_timeout, read_timeout);
CloseableHttpResponse response = null;
try{
if(headers!=null){
java.util.Iterator iter = headers.entrySet().iterator();
while (iter.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
httpreq.addHeader(key, value);
}
}
response = httpclient.execute(httpreq);
int statecode = response.getStatusLine().getStatusCode();
String responsestring = "";
HttpEntity entity = response.getEntity();
responsestring = entity==null ? "" : EntityUtils.toString(entity, "utf-8");
KHttpResponse httpresponse = new KHttpResponse(statecode, responsestring);
return httpresponse;
}catch(IOException e){
throw e;
}finally{
if(response!=null){
try{
response.close();
}catch(IOException e){}
}
}
}
/****************** 上传工具函数(POST方式) ******************/
//POST上传: 数据流放在REQUEST-BODY中
public static KHttpResponse doPostBody(final String urladdr, final Map headers,
final InputStream bodyStream, final long bodySize, final int connect_timeout, final int read_timeout) throws IOException{
CloseableHttpClient httpclient = getHttpClient(urladdr, connect_timeout, read_timeout);
CloseableHttpResponse response = null;
try{
HttpPost post = new HttpPost(urladdr);
//构造请求头
if(headers!=null){
java.util.Iterator iter = headers.entrySet().iterator();
while (iter.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
post.addHeader(key, value);
}
}
post.setEntity(new InputStreamEntity(bodyStream, bodySize));
//发起请求:
response = httpclient.execute(post);
//返回:
int statecode = response.getStatusLine().getStatusCode();
String responsestring = "";
HttpEntity entity = response.getEntity();
responsestring = entity==null ? "" : EntityUtils.toString(entity, "utf-8");
KHttpResponse httpresponse = new KHttpResponse(statecode, responsestring);
return httpresponse;
}catch(IOException e){
throw e;
}finally{
if(response!=null){
try{
response.close();
}catch(IOException e){}
}
}
}
public static KHttpResponse doPostJson(final String url, final Map headers,final String json) throws Exception {
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
return request(httpPost, headers, 3000, 3000);
}
//POST上传: 数据流放在REQUEST-MULTIPARTFORM中
public static KHttpResponse doPostMultipart(final String urladdr, final InputStream srcstream) throws IOException{
return doPostMultipart(urladdr, srcstream, null);
}
public static KHttpResponse doPostMultipart(final String urladdr, final InputStream srcstream, final Map headers) throws IOException{
return doPostMultipart(urladdr, headers, null, "file", srcstream, -1, 30000, 30000);
}
public static KHttpResponse doPostMultipart(final String urladdr,
final Map headers, final Map multiformdatamap,
final String datakey,
final InputStream datastream,
final long datalen, //数据长度如果未知,则填写-1
final int connect_timeout, final int read_timeout) throws IOException{
CloseableHttpClient httpclient = getHttpClient(urladdr, connect_timeout, read_timeout);
CloseableHttpResponse response = null;
try{
HttpPost post = new HttpPost(urladdr);
//构造请求头
if(headers!=null){
java.util.Iterator iter = headers.entrySet().iterator();
while (iter.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
post.addHeader(key, value);
}
}
//构造表单域
MultipartEntityBuilder mb = MultipartEntityBuilder.create();
mb.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if(multiformdatamap!=null){
Iterator iter = multiformdatamap.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, String> entry = (Entry<String, String>)iter.next();
String name = (String) entry.getKey();
String text = (String) entry.getValue();
mb.addTextBody(name, text);
}
}
if(datalen>=0){
//指定长度:
class KnownSizeInputStreamBody extends InputStreamBody {
private final long contentLength;
public KnownSizeInputStreamBody(InputStream in, long contentLength) {
super(in, ContentType.APPLICATION_OCTET_STREAM, datakey);
this.contentLength = contentLength;
}
@Override
public long getContentLength() {
return contentLength;
}
}
mb.addPart(datakey, new KnownSizeInputStreamBody(datastream, datalen));
}else{
mb.addBinaryBody(datakey, datastream, ContentType.DEFAULT_BINARY, datakey);
}
post.setEntity( mb.build() );
//发起请求:
response = httpclient.execute(post);
int statecode = response.getStatusLine().getStatusCode();
String responsestring = "";
HttpEntity entity = response.getEntity();
responsestring = entity==null ? "" : EntityUtils.toString(entity, "utf-8");
KHttpResponse httpresponse = new KHttpResponse(statecode, responsestring);
return httpresponse;
}catch(IOException e){
throw e;
}finally{
if(response!=null){
try{
response.close();
}catch(IOException e){}
}
}
}
/****************** 下载工具函数(GET方式) ******************/
//执行操作--下载数据流:
public static final InputStream doDownloadStream(final String downloadurl, Map headers) throws IOException{
CloseableHttpClient httpclient = getHttpClient(downloadurl, 30000, 30000);
try{
HttpGet httpreq = new HttpGet(downloadurl);
if(headers!=null){
java.util.Iterator iter = headers.entrySet().iterator();
while (iter.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
httpreq.addHeader(key, value);
}
}
CloseableHttpResponse response = httpclient.execute(httpreq);
int statecode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if(statecode==200 || statecode==206){
//操作成功...
InputStream instream = entity.getContent();
return instream;
}else{
//遇到异常了...
String responsestring = entity==null ? "" : EntityUtils.toString(entity, "utf-8");
throw new IOException("Http response code="+String.valueOf(statecode)+", Error="+responsestring);
}
}catch(IOException e){
throw e;
}
}
//断点续传的处理接口:
public interface KHttpBreakpointDownloadHandler {
public long getHandledDatasize(); //当前已经下载了的字节数
public void doHandleDatas(InputStream instream) throws Exception; //处理下载数据
}
//执行断点下载操作:
public static void doBreakpointDownload(String srcurl, long srcurlsize, KHttpBreakpointDownloadHandler handler, int maxretrytimes) throws Exception{
if(handler==null)
return;
//执行断点下载:
Exception error = null;
int DownloadFailedTimes = 0;
CloseableHttpClient httpclient = getHttpClient(srcurl, 30000, 30000);
while(true){
Exception tmperror = null;
long tmpStartPos = 0;
CloseableHttpResponse response = null;
InputStream instream = null;
try {
HttpGet httpreq = new HttpGet(srcurl);
//如果是断点续传,则我们指定从断点处开始下载数据:
tmpStartPos = handler.getHandledDatasize();
if(tmpStartPos>0){
httpreq.addHeader("Range", "bytes="+String.valueOf(tmpStartPos)+"-");
}
response = httpclient.execute(httpreq);
int statecode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if(statecode==200 || statecode==206){
//操作成功...
instream = entity.getContent();
//处理instream:
try{
handler.doHandleDatas(instream);
}catch(Exception er){
throw er;
}
}else{
//遇到异常了...
String responsestring = entity==null ? "" : EntityUtils.toString(entity, "utf-8");
throw new IOException("Http response code="+String.valueOf(statecode)+", Error="+responsestring);
}
}catch(Exception e){
tmperror = e;
} finally {
if(instream!=null)
instream.close();
if(response!=null)
response.close();
}
long totaldownsize = handler.getHandledDatasize();
if( totaldownsize>=srcurlsize ){
//我们已经下载完毕所有文件内容了...
//下载操作完毕.
break;
}
if(totaldownsize>tmpStartPos){
//本轮已经下载了一些数据, 我们再试试
DownloadFailedTimes = 0;
continue;
}else{
//本轮一个字节都没有下载到...
DownloadFailedTimes++;
if(DownloadFailedTimes>=maxretrytimes){
if(tmperror!=null){
error = tmperror;
}else{
error = new Exception("BreakpointDownload failed:"+srcurl);
}
break;
}else{
continue;
}
}
}
if(error!=null){
throw error;
}
}
}
美滋滋