All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wicp.tams.common.http.HttpCallAbs Maven / Gradle / Ivy

The newest version!
/*
 * **********************************************************************
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称:common
 * 项目描述:公共的工具集
 * 版权说明:本软件属andy.zhou([email protected])所有。
 * ***********************************************************************
 */
package net.wicp.tams.common.http;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import net.wicp.tams.common.Conf;
import net.wicp.tams.common.apiext.DateUtil;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.thread.ThreadPool;

/***
 * 不会自动销毁。只有在线程池中产生且非saveSession会自动销毁
 * 
 * @author Andy.zhou
 *
 */
public abstract class HttpCallAbs {

	private final CloseableHttpClient httpClient;
	// private final HttpContext context;
	// private final HttpRequestBase httpReq;
	protected final AuthCache authCache;

	protected final CookieStore cookieStore;

	public HttpCallAbs(boolean saveSession, CookieStore cookieStore) {
		this(Conf.get("common.http.url.protocol"), Conf.get("common.http.url.host"),
				Conf.getInt("common.http.url.port"), Conf.get("common.http.username"), Conf.get("common.http.pwd"),
				saveSession, cookieStore);
	}

	public HttpCallAbs(String protocol, String host, int port, String username, String pwd, boolean saveSession,
			CookieStore cookieStore) {
		this.cookieStore = cookieStore;
		if (StringUtil.isNotNull(username) && StringUtil.isNotNull(pwd)) {
			HttpHost httpHost = new HttpHost(host, port, protocol);
			CredentialsProvider credsProvider = new BasicCredentialsProvider();
			credsProvider.setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(username, pwd));
			// this.httpClient =
			// HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
			this.httpClient = HttpConnPool.getInstance().newHttpClient(credsProvider, saveSession, cookieStore);
			// ((HttpClientContext) this.context).setAuthCache(authCache);
			// 认证缓存
			this.authCache = new BasicAuthCache();
			BasicScheme basicAuth = new BasicScheme();
			this.authCache.put(httpHost, basicAuth);
		} else {
			// this.httpClient = HttpClients.custom().build();
			this.httpClient = HttpConnPool.getInstance().newHttpClient(null, saveSession, cookieStore);
			this.authCache = null;
		}
	}

	public HttpResult call(HttpRequestBase httpReq) {
		return call(httpReq, null);
	}

	public HttpResult call(HttpRequestBase httpReq, HttpContext context) {
		//System.setProperty("apache.commons.httpclient.cookiespec", CookiePolicy.BROWSER_COMPATIBILITY);
		httpReq.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58");
		HttpResult ret = new HttpResult();
		try {
			if (context == null) {
				context = HttpClientContext.create();
			}
			if (this.authCache != null) {// 需要认证
				((HttpClientContext) context).setAuthCache(authCache);
			}
			CloseableHttpResponse response = httpClient.execute(httpReq, context);

			int statusCode = response.getStatusLine().getStatusCode();
//			if(statusCode==HttpStatus.SC_MOVED_TEMPORARILY) {//临时重定向
//			        Header firstHeader = response.getFirstHeader("Location");
//				
//			}
			HttpEntity entity = null;
			try {
				entity = response.getEntity();
				ret.setContext(context);
				ret.setBody(IOUtils.toByteArray(entity.getContent()));
				ret.setContentLength(entity.getContentLength());
				ret.setContentType(entity.getContentType());
				ret.setContentEncoding(entity.getContentEncoding());
				ret.setStatusLine(response.getStatusLine());
			} finally {
				// 是一直占用着资源的,而资源回收资源线程是将空闲的、失效的连接回收,所以我们需要手动去关闭资源占用
				EntityUtils.consume(entity);
				response.close();
			}
		} catch (Exception ex) {
			ret.setErrMsg(ex.getMessage());
		}
		return ret;
	}

	/***
	 * 通过cookie字符得到BasicClientCookie对象
	 * 
	 * @param defaultDomain 默认domain
	 * @param cookieStr
	 * @return
	 */
	protected BasicClientCookie getCookie(String defaultDomain, String cookieStr) {
		String[] eles = cookieStr.split(";");
		String[] ele0 = eles[0].split("=");
		BasicClientCookie ret = new BasicClientCookie(ele0[0], ele0[1]);
		for (int i = 1; i < eles.length; i++) {
			String[] ele = eles[i].split("=");
			switch (ele[0]) {
			case "domain":
				ret.setDomain(ele[1]);
				break;
			case "path":
				ret.setPath(ele[1]);
				break;
			case "Max-Age":
				Date maxAge = DateUtil.setDifMillisecond(new Date(), Integer.parseInt(ele[1]) * 1000);
				ret.setExpiryDate(maxAge);
				break;
			default:
				break;
			}
		}
		if (StringUtil.isNull(ret.getDomain())) {
			ret.setDomain(defaultDomain);
		}
		return ret;
	}

	/***
	 * 异步调用,如果不需要返回值可忽略,如果需要返回值用 task.get(); 会阻塞线程
	 */
	public FutureTask callAsyn(HttpRequestBase httpReq, HttpContext context) {
		HttpCallAbs httpCallAbs = this;
		FutureTask task = new FutureTask(new Callable() {
			@Override
			public HttpResult call() throws Exception {
				return httpCallAbs.call(httpReq, context);
			}
		});
		ThreadPool.getDefaultPool().submit(task);
		return task;
	}

	public HttpResult callBlock(HttpRequestBase httpReq, HttpContext context) {
		FutureTask task = callAsyn(httpReq, context);
		HttpResult ret = null;
		try {
			ret = task.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return ret;
	}

	// 手动关闭httpClient
	public void close() {
		try {
			this.httpClient.close();
		} catch (Exception e) {
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy