http client 工具类
2018-07-20 来源:open-open
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(); } } }
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。
上一篇:android判断横竖屏
最新资讯
热门推荐