http client 工具类

2018-07-20    来源:open-open

容器云强势上线!快速搭建集群,上万Linux镜像随意使用

HttpConn    

public class HttpConn {

	private final static Logger logger = LoggerFactory.getLogger(HttpConn.class); 
	
	//MIME-TYPE
	public static final String MIME_TYPE_PLAIN = "text/plain";
	public static final String MIME_TYPE_XML = "text/xml";
	public static final String MIME_TYPE_HTML = "text/html";
	public static final String MIME_TYPE_JSON = "application/json";
	
	//REQUEST METHOD
	public static final String METHOD_GET = "GET"; 
	public static final String METHOD_POST = "POST";
	
	//HTTP STATUS
	public static final int HTTP_RESSTATUS_SUCCESS = 200;
	public static final int HTTP_RESSTATUS_NOT_FOUND = 404;
	
	//Default Values
	public static final String DETAULT_ENCODING = "UTF-8";
	public static final Charset DEFAULT_CHARSET = Consts.UTF_8;  
	public static final int REQUEST_TIMEOUT = 5 * 1000; // 请求超时时间
	public static final int CONNECTION_TIMEOUT = 10 * 1000; // 连接超时时间  
	public static final int SOCKET_TIMEOUT = 10 * 1000; // 数据传输超时  
	public static final int POOL_MAX_SIZE = 200; // 连接池最大连接数
	public static final int POOL_MAX_SIZE_PER_ROUTER = 200; // 每个路由最大连接数
    
    //Request Params
	private String reqUrl;
	private String reqMethod;
	private Map<String, String> reqParams;//请求参数
	private String reqPostString;//post内容
	private String reqCharset;
	private String reqContentType;//请求内容类型
	private String reqFileKey;//上传文件在form-data的key值
	private String reqFilePath;//上传的文件路径
	//Response Infos
	private int resCode;
	private boolean resSuccess = false;//是否正常响应,即返回200
	private String resStatues;
	private long resLength;
	private String resEncoding;
	private String resContentType;
	private String resBody;
	private String resFilePath;
	private boolean resFileSaveSuccess = false;//响应文件是否保存成功
	
	//
    private static PoolingHttpClientConnectionManager cm = null;  
    private static CloseableHttpClient client = null;  
    
    private HttpUriRequest request = null;
    private CloseableHttpResponse response = null;
    
    /**
     * 初始化连接池与Client
     * */
    static{
    	try {
			// 初始化SSL环境
			SSLContextBuilder sslContextbuilder = new SSLContextBuilder();  
			sslContextbuilder.useTLS();  
			SSLContext sslContext = sslContextbuilder.loadTrustMaterial(null, new TrustStrategy() {  
			    // 信任所有  
			    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException  
			    {  
			        return true;  
			    }  

			}).build();
			
			//注册协议
			ConnectionSocketFactory plainCSF = PlainConnectionSocketFactory.INSTANCE;
			ConnectionSocketFactory sslCSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()  
		            .register("http", plainCSF)  
		            .register("https", sslCSF)
		            .build(); 
			
			// 创建连接池
			cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 
			
			// 初始化Socket配置
            SocketConfig socketConfig = SocketConfig.custom()
            							.setTcpNoDelay(true)
            							.build();  
            cm.setDefaultSocketConfig(socketConfig);  
            
            // Http消息约束
//            MessageConstraints messageConstraints = MessageConstraints.custom().
//            				setMaxHeaderCount(200).
//            				setMaxLineLength(2000).build();  
            
            // http连接设置 
            ConnectionConfig connectionConfig = ConnectionConfig.custom()  
                    .setMalformedInputAction(CodingErrorAction.IGNORE)  //忽略不合法的输入
                    .setUnmappableInputAction(CodingErrorAction.IGNORE)   //忽略不匹配的输入
                    .setCharset(DEFAULT_CHARSET)  
//                    .setMessageConstraints(messageConstraints)
                    .build();  
  
            cm.setDefaultConnectionConfig(connectionConfig);  
            cm.setMaxTotal(POOL_MAX_SIZE);  //连接池最大连接数
            cm.setDefaultMaxPerRoute(POOL_MAX_SIZE_PER_ROUTER);  //每个路由最大连接数  
            
            // 请求设置
            RequestConfig requestConfig = RequestConfig.custom()
            								.setConnectionRequestTimeout(REQUEST_TIMEOUT) //请求超时
            								.setSocketTimeout(SOCKET_TIMEOUT)  //Socket超时
            								.setConnectTimeout(CONNECTION_TIMEOUT)  //连接超时
            								.build();
            
            // 创建HttpClient  
            client = HttpClients.custom()
            			.disableRedirectHandling()
            			.setConnectionManager(cm)
            			.setDefaultRequestConfig(requestConfig)
            			.build();  
            
            // 启动连接池监控线程
            HttpConnMonitorThread monitor = new HttpConnMonitorThread(cm);
            monitor.start();
		} catch (KeyManagementException e) {
			logger.error("", e);
		} catch (NoSuchAlgorithmException e) {
			logger.error("", e);
		} catch (KeyStoreException e) {
			logger.error("", e);
		}  
    }
    
    /**
     * 设置请求、连接、获取响应
     * */
    public boolean connect() throws ParseException, UnsupportedEncodingException, IOException {
		try {
			setReqInfo();
			if(CommonUtil.isEmpty(this.request)){
				throw new RuntimeException("HttpConn ,初始化请求失败!");
			}
			//执行连接,返回响应
			HttpClientContext context = HttpClientContext.create();
			this.response = client.execute(this.request, context);
			//处理响应结果
			if(CommonUtil.isEmpty(this.response)){
				throw new RuntimeException("HttpConn ,响应获取失败!");
			}
			setResInfo();
		} finally {
			try {
				if(this.response != null)
					this.response.close();
			} catch (IOException e) {
				logger.error(e.getMessage());
			}
		} 
		return true;
	}
    
    /**
     * 设置请求参数
     * */
    private void setReqInfo() throws ParseException, UnsupportedEncodingException, IOException{
		if(!CommonUtil.isEmpty(this.reqFilePath))//上传,使用POST
			this.reqMethod = METHOD_POST;
		if(!CommonUtil.isEmpty(this.reqPostString))//post参数,使用POST
			this.reqMethod = METHOD_POST;
		if(CommonUtil.isEmpty(this.reqMethod))
			this.reqMethod = METHOD_GET;
		
		if(CommonUtil.isEmpty(this.reqContentType)) //设置内容类型,默认为text/plain
			this.reqContentType = MIME_TYPE_PLAIN;
		if(CommonUtil.isEmpty(this.reqCharset))  //设置编码格式
			this.reqCharset = DETAULT_ENCODING;
		
		//将请求参数转换为字符串形式
		String paramString = null;
		if(!CommonUtil.isEmpty(this.reqParams)){
			List<NameValuePair> paramList = new ArrayList<NameValuePair>();
			Iterator<Map.Entry<String, String>> it = this.reqParams.entrySet().iterator();
			while(it.hasNext()){
				Map.Entry<String, String> entry = it.next();
				paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
			paramString = EntityUtils.toString(new UrlEncodedFormEntity(paramList, this.reqCharset == null?DETAULT_ENCODING : this.reqCharset));
		}
		
		//GET请求
		if(this.reqMethod.equalsIgnoreCase(METHOD_GET)){
			//设置请求参数
			if(!CommonUtil.isEmpty(paramString)){
				if(this.reqUrl.trim().lastIndexOf("?") == -1){
					this.reqUrl += "?" + paramString;
				}else{
					this.reqUrl += "&" + paramString;
				}
			}
			//创建Get请求
			HttpGet get = new HttpGet(this.reqUrl);
			this.request = get;
		}
		//POST请求
		else if(this.reqMethod.equals(METHOD_POST)){
			HttpPost post = new HttpPost(this.reqUrl);
			//post请求参数
			if(!CommonUtil.isEmpty(this.reqPostString) || !CommonUtil.isEmpty(paramString)){
				reqPostString = (reqPostString==null ? paramString : reqPostString);
				StringEntity entity = null;
				entity = new StringEntity(this.reqPostString, ContentType.create(this.reqContentType,this.reqCharset));
				post.setEntity(entity);
			}
			//上传文件
			else if(!CommonUtil.isEmpty(this.reqFilePath)){
				MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
				//以浏览器兼容模式运行,防止文件名乱码
				entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//				entityBuilder.setCharset(Consts.UTF_8);//设置编码格式
				//设置文件信息
				File uploadFile = new File(this.reqFilePath);
				if(!uploadFile.exists()){
					throw new RuntimeException("HttpConn:\""+reqFilePath+"\"路径不存在!");
				}else{
					if(CommonUtil.isEmpty(this.reqFileKey))
						throw new RuntimeException("HttpConn: resFileKey为空!");
					entityBuilder.addBinaryBody(this.reqFileKey, uploadFile);
				}
				//设置参数信息
				if(!CommonUtil.isEmpty(this.reqParams)){
					Iterator<Map.Entry<String, String>> it = this.reqParams.entrySet().iterator();
					while(it.hasNext()){
						Map.Entry<String, String> entry = it.next();
						String key = entry.getKey();
						StringBody body = new StringBody(entry.getValue(), ContentType.create("text/plain", DETAULT_ENCODING));
						entityBuilder.addPart(key, body);
					}
				}
				post.setEntity(entityBuilder.build());
			}
			
			this.request = post;
		}
	}
    
    /**
	 * 处理响应数据
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	private void setResInfo() throws IllegalStateException, IOException {
		HttpEntity resEntity = this.response.getEntity();
		//返回状态
		this.resCode = this.response.getStatusLine().getStatusCode();
		this.resStatues = this.response.getStatusLine().toString();
		this.resLength = resEntity.getContentLength();
		if(!CommonUtil.isEmpty(resEntity.getContentEncoding()))
			this.resEncoding = resEntity.getContentEncoding().getValue();
		if(this.resCode == HTTP_RESSTATUS_SUCCESS){
			resSuccess = true;
			//返回数据
			this.resContentType = resEntity.getContentType().getValue();
			if(CommonUtil.isEmpty(this.resEncoding)){
				this.resEncoding = getEncoding(this.resContentType);
			}
			InputStream is = null;
			FileOutputStream fos = null;
			try{
				is = resEntity.getContent();
				//保存为文件
				if(!CommonUtil.isEmpty(this.resFilePath)){
					if(!CommonUtil.isFilePath(this.resFilePath)){
						//从请求头获取文件名
						String fileName = getValueFromHeader("Content-disposition", "filename");
						if(fileName != null){
							this.resFilePath += "_"+fileName;
						}
					}
					File downFile = new File(this.resFilePath);
					downFile.getParentFile().mkdirs();
					fos = new FileOutputStream(downFile);
					resEntity.writeTo(fos);
					this.resFileSaveSuccess = true;
				}
				//保存为字符串
				else{
					if(CommonUtil.isEmpty(this.resEncoding))
						this.resBody = EntityUtils.toString(resEntity, Consts.UTF_8);
					else
						this.resBody = EntityUtils.toString(resEntity, this.resEncoding);
				}
				
			}finally{
				try {
					if(is != null)
						is.close();
					if(fos != null)
						fos.close();
				} catch (Exception e) {
					throw new RuntimeException("HttpConn : " + e.getMessage());
				}
			}
		}else{
			this.request.abort();//中止请求
			throw new RuntimeException("HttpConn ,error status code : " + this.resCode);
		}
		//销毁
		EntityUtils.consume(resEntity);
	}
	
	/**
	 * 从content-type获取编码格式
	 * @param contentType
	 * @return
	 */
	private String getEncoding(String contentType) {
		String encoding = null;
		int tmp = contentType.indexOf(";");
		if(tmp > 0){
			encoding = contentType.substring(tmp+1);
			encoding = encoding.trim();
			tmp = encoding.indexOf("=");
			if(tmp > 0){
				String[] entry = encoding.split("=");
				if(entry[0].equalsIgnoreCase("charset") || entry[0].equalsIgnoreCase("encoding"))
					encoding = entry[1].trim();
			}
		}
		
		return encoding;
	}


	/**
	 * 从请求头中获取参数值
	 * @param headerName
	 * @param key
	 * @return
	 */
	private String getValueFromHeader(String headerName, String key) {
		String value = null;
		Header header = this.response.getFirstHeader(headerName);
		
		if(!CommonUtil.isEmpty(header)){
			if(CommonUtil.isEmpty(key)){
				value = header.getValue();
			}else{
				HeaderElement[] elms = header.getElements();
				for(HeaderElement elm : elms){
					NameValuePair pair = elm.getParameterByName(key);
					if(pair != null){
						value = pair.getValue();
						break;
					}
				}
			}
		}
		
		return value;
	}
	
	public void setReqFilePath(String reqFileKey, String reqFilePath) {
		this.reqFileKey = reqFileKey;
		this.reqFilePath = reqFilePath;
	}

	public int getResCode() {
		return resCode;
	}

	public String getResStatues() {
		return resStatues;
	}

	public String getResType() {
		return resContentType;
	}

	public String getResBody() {
		return resBody;
	}

	public void setReqUrl(String reqUrl) {
		this.reqUrl = reqUrl;
	}

	public void setReqMethod(String reqMethod) {
		this.reqMethod = reqMethod;
	}

	public void setReqParams(Map<String, String> reqParams) {
		this.reqParams = reqParams;
	}

	public void setReqPostString(String reqPostString) {
		this.reqPostString = reqPostString;
	}

	
	
	public void setReqContentType(String reqContentType) {
		this.reqContentType = reqContentType;
	}


	public void setResFilePath(String resFilePath) {
		this.resFilePath = resFilePath;
	}


	public long getResLength() {
		return resLength;
	}


	public String getResEncoding() {
		return resEncoding;
	}


	public String getResContentType() {
		return resContentType;
	}


	public boolean isResFileSaveSuccess() {
		return resFileSaveSuccess;
	}


	public void setReqCharset(String reqCharset) {
		this.reqCharset = reqCharset;
	}


	public boolean isResSuccess() {
		return resSuccess;
	}


	public void setResSuccess(boolean resSuccess) {
		this.resSuccess = resSuccess;
	}
    
	
}

HttpConnMonitorThread    

public class HttpConnMonitorThread extends Thread{
	
	private final static Logger logger = LoggerFactory.getLogger(HttpConnMonitorThread.class); 
	
	private final HttpClientConnectionManager cm;
    private volatile boolean shutdown;
    
    private final static int WATING_TIME = 60 * 1000; // 轮询时间
    private final static int IDLE_TIME = 30; // 空闲时间
    
    public HttpConnMonitorThread(HttpClientConnectionManager cm) {
        super();
        this.cm = cm;
    }

    @Override
    public void run() {
        try {
            while (!shutdown) {
                synchronized (this) {
                    wait(WATING_TIME);
                    // 关闭过期连接
                    cm.closeExpiredConnections();
                    logger.info(">>>>>close expired connections.");
                    // 关闭空闲连接
                    cm.closeIdleConnections(IDLE_TIME, TimeUnit.SECONDS);
                    logger.info(">>>>>close idle connections.");
                }
            }
        } catch (InterruptedException ex) {
            logger.error("HttpConn Monitor error! ", ex);
        }
    }
    
    /**
     * 关闭轮询
     */
    public void shutdown() {
        shutdown = true;
        synchronized (this) {
            notifyAll();
        }
    }
	
}

标签: isp ssl

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:android判断横竖屏

下一篇:把android activity修改为悬浮窗口