package com.walker.remote.support; import com.walker.infrastructure.utils.FileCopyUtils; import com.walker.infrastructure.utils.JsonUtils; import com.walker.infrastructure.utils.StringUtils; import com.walker.remote.Constants; import com.walker.remote.DoubleTrust; import com.walker.remote.RemoteAccessor; import com.walker.remote.RemoteAccessorException; import com.walker.remote.RemoteSyncTask; import com.walker.remote.ResultData; import com.walker.remote.util.HttpUtils; import org.apache.hc.client5.http.ClientProtocolException; import org.apache.hc.client5.http.classic.methods.HttpDelete; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpPut; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.cookie.CookieStore; import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.util.Timeout; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.GZIPInputStream; public class HttpRemoteTask extends RemoteSyncTask { private DoubleTrust doubleTrust; private CloseableHttpClient httpDoubleClient = null; // private int httpReadTimeout = 60 * 1000; private Timeout httpReadTimeout = Timeout.ofSeconds(60); private RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(Timeout.ofSeconds(1)).setConnectTimeout(Timeout.ofSeconds(30)) .setResponseTimeout(httpReadTimeout).build(); private final Charset UTF8_CHAR_SET = Charset.forName(StringUtils.DEFAULT_CHARSET_UTF8); public Timeout getHttpReadTimeout() { return httpReadTimeout; } public void setHttpReadTimeout(Timeout httpReadTimeout) { this.httpReadTimeout = httpReadTimeout; } public void setDoubleTrust(DoubleTrust doubleTrust) { this.doubleTrust = doubleTrust; } /** * 2020-07-06添加新方法,适应更多场景 */ @Override protected String requestForData(Map simpleData, String url, String jsonData , String methodType, String contentType, Map header) throws RemoteAccessorException { boolean methodOfPost = true; // 使用post提交方式 // HttpResponse response = null; CloseableHttpResponse response = null; // HttpClient httpClient = null; CloseableHttpClient httpClient = null; if(doubleTrust == null){ httpClient = (CloseableHttpClient)HttpUtils.getInstance().getHttpClient(); } else { if(httpDoubleClient == null){ httpDoubleClient = (CloseableHttpClient)HttpUtils.getInstance().getHttpDoubleTrustClient(doubleTrust, null); logger.debug(".............创建了一个https连接:" + doubleTrust); } httpClient = httpDoubleClient; } HttpGet get = null; HttpUriRequestBase httpMethod = null; try{ if((methodType != null && methodType.equals(Constants.HTTP_METHOD_GET)) || (simpleData == null && (jsonData == null || jsonData.equals(StringUtils.EMPTY_STRING)))){ // get单独处理 methodOfPost = false; get = new HttpGet(url); get.setConfig(requestConfig); if(StringUtils.isNotEmpty(contentType)){ get.setHeader("Content-Type", contentType); } this.addHeader(header, get); response = httpClient.execute(get); } else if(methodType != null) { if(methodType.equals(Constants.HTTP_METHOD_POST)){ httpMethod = new HttpPost(url); } else if(methodType.equals(Constants.HTTP_METHOD_PUT)){ httpMethod = new HttpPut(url); } else if(methodType.equals(Constants.HTTP_METHOD_DELETE)){ httpMethod = new HttpDelete(url); } else { throw new IllegalArgumentException("不支持的请求方法:" + methodType); } httpMethod.setConfig(requestConfig); if(StringUtils.isNotEmpty(contentType)){ httpMethod.setHeader("Content-Type", contentType); } this.addHeader(header, httpMethod); // HttpEntityEnclosingRequest httpRequest = (HttpEntityEnclosingRequest)httpMethod; HttpUriRequestBase httpRequest = (HttpUriRequestBase)httpMethod; List pair = null; Charset utf8 = Charset.forName(StringUtils.DEFAULT_CHARSET_UTF8); if(simpleData != null){ // 只处理简单参 pair = HttpUtils.doTranslatePairs(simpleData); httpRequest.setEntity(new UrlEncodedFormEntity(pair, utf8)); } if(StringUtils.isNotEmpty(jsonData)){ if (getContentCoder() != null) { byte[] byteParams = jsonData.getBytes(StringUtils.DEFAULT_CHARSET_UTF8); String enString = new String(getContentCoder().encrypt(byteParams)); logger.debug("---reuqest-----"+enString); httpRequest.setEntity(new StringEntity(enString, utf8)); } else { httpRequest.setEntity(new StringEntity(jsonData, utf8)); } } response = httpClient.execute(httpMethod); } // final int statusCode = response.getStatusLine().getStatusCode(); final int statusCode = response.getCode(); if(statusCode == Constants.HTTP_SUCCESS){ HttpEntity entity = response.getEntity(); if(entity == null){ return null; } byte[] result = FileCopyUtils.copyToByteArray(getInputStream(response, entity)); if(getContentCoder() == null){ // 没有编码器 return new String(result, StringUtils.DEFAULT_CHARSET_UTF8); } byte[] descrypt = getContentCoder().decrypt(result); return new String(descrypt, StringUtils.DEFAULT_CHARSET_UTF8); } else { if(methodOfPost){ if(httpMethod != null){ httpMethod.abort(); } } else { if(get != null){ get.abort(); } } } return null; } catch(ClientProtocolException ce){ throw new RemoteAccessorException("httpClient协议错误", ce); } catch(IOException ioe){ throw new RemoteAccessorException("httpClient连接异常IO", ioe, true); } catch(Exception ex){ throw new RemoteAccessorException("httpClient请求转换结果错误:computeResult()", ex); } finally { } } private void addHeader(Map header, HttpUriRequestBase request){ if(header != null){ for(Map.Entry entry : header.entrySet()){ request.setHeader(entry.getKey(), entry.getValue()); } } } @Override protected String requestForData(Map simpleData, String url, String jsonData) throws RemoteAccessorException { boolean methodOfPost = true; // 使用post提交方式 // CloseableHttpResponse response = null; CloseableHttpResponse response = null; CloseableHttpClient httpClient = null; if(doubleTrust == null){ httpClient = (CloseableHttpClient) HttpUtils.getInstance().getHttpClient(); } else { if(httpDoubleClient == null){ httpDoubleClient = (CloseableHttpClient) HttpUtils.getInstance().getHttpDoubleTrustClient(doubleTrust, null); logger.debug(".............创建了一个https连接:" + doubleTrust); } httpClient = httpDoubleClient; } try{ HttpGet get = null; HttpPost post = null; if(simpleData == null && (jsonData == null || jsonData.equals(StringUtils.EMPTY_STRING))){ // 无参数,默认使用Get请求 methodOfPost = false; get = new HttpGet(url); get.setConfig(requestConfig); response = httpClient.execute(get); } else { // 有参数,使用post提交,但是需要使用表单方式 post = new HttpPost(url); post.setConfig(requestConfig); List pair = null; Charset utf8 = Charset.forName(StringUtils.DEFAULT_CHARSET_UTF8); if(simpleData != null){ // 只处理简单参 pair = HttpUtils.doTranslatePairs(simpleData); post.setEntity(new UrlEncodedFormEntity(pair, utf8)); } else { // 处理json复杂参数 // pair = HttpUtils.doTranslatePairs(jsonData); // 加密 ---李润015-09-02 if (getContentCoder() != null) { byte[] byteParams = jsonData.getBytes(StringUtils.DEFAULT_CHARSET_UTF8); String enString = new String(getContentCoder().encrypt(byteParams)); logger.debug("---reuqest-----"+enString); post.setEntity(new StringEntity(enString, utf8)); } else { post.setEntity(new StringEntity(jsonData, utf8)); } } // post.setEntity(new StringEntity(params[1], HTTP.UTF_8)); // post.setEntity(new UrlEncodedFormEntity(pair, HTTP.UTF_8)); response = httpClient.execute(post); } final int statusCode = response.getCode(); if (statusCode == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if(entity != null){ // 把接收到的字节解�? // byte[] result = FileCopyUtils.copyToByteArray(entity.getContent()); // byte[] decodeResult = this.getContentCoder().decrypt(result); //2015-07-29 增加压缩判断 李润冬,解压缩还未测�? byte[] result=FileCopyUtils.copyToByteArray(getInputStream(response, entity)); //解密 李润�?015-07-28 if(getContentCoder()!=null){ byte[] descrypt = getContentCoder().decrypt(result); // if(timeRecorder != null){ // timeRecorder.setDecryptTime(tester.getTotalTime()); // } return new String(descrypt); }else{ return new String(result); } } else { return null; } } else if(statusCode > 200 && statusCode <= 507){ /* 时克英添加,2018-03-07 */ Map extendData = new HashMap<>(); extendData.put("code", statusCode); extendData.put("location", response.getFirstHeader("Location")); return RemoteAccessor.RESPONSE_EXT_ID + JsonUtils.objectToJsonString(extendData); } else if(methodOfPost){ post.abort(); logger.error("服务调用完成,但返回错误代码:" + statusCode); } else { get.abort(); logger.error("服务调用完成,但返回错误代码:" + statusCode); } return null; } catch(ClientProtocolException ce){ throw new RemoteAccessorException("httpClient协议错误", ce); } catch(IOException ioe){ throw new RemoteAccessorException("httpClient连接异常IO", ioe, true); } catch(Exception ex){ throw new RemoteAccessorException("httpClient请求转换结果错误:computeResult()", ex); } finally { } } @Override protected ResultData requestForDataAndCookie(Map simpleData , String url, String jsonData, CookieStore cookieStore) throws RemoteAccessorException { boolean methodOfPost = true; // 使用post提交方式 // CloseableHttpResponse response = null; CloseableHttpResponse response = null; ResultData resultData = new ResultData(); CloseableHttpClient httpClient = null; if(doubleTrust == null){ // httpClient = HttpUtils.getInstance().getHttpClient(); httpClient = (CloseableHttpClient) HttpUtils.getInstance().getHttpClientWithCookie(cookieStore); } else { if(httpDoubleClient == null){ httpDoubleClient = (CloseableHttpClient) HttpUtils.getInstance().getHttpDoubleTrustClient(doubleTrust, cookieStore); logger.debug(".............创建了一个https连接:" + doubleTrust); } httpClient = httpDoubleClient; } try{ HttpGet get = null; HttpPost post = null; if(simpleData == null && (jsonData == null || jsonData.equals(StringUtils.EMPTY_STRING))){ // 无参数,默认使用Get请求 methodOfPost = false; get = new HttpGet(url); get.setConfig(requestConfig); response = httpClient.execute(get); } else { // 有参数,使用post提交,但是需要使用表单方式 post = new HttpPost(url); post.setConfig(requestConfig); List pair = null; if(simpleData != null){ // 只处理简单参 pair = HttpUtils.doTranslatePairs(simpleData); post.setEntity(new UrlEncodedFormEntity(pair, UTF8_CHAR_SET)); } else { // 处理json复杂参数 // pair = HttpUtils.doTranslatePairs(jsonData); // 加密 ---李润015-09-02 if (getContentCoder() != null) { byte[] byteParams = jsonData.getBytes(StringUtils.DEFAULT_CHARSET_UTF8); String enString = new String(getContentCoder().encrypt(byteParams)); logger.debug("---reuqest-----"+enString); post.setEntity(new StringEntity(enString, UTF8_CHAR_SET)); } else { post.setEntity(new StringEntity(jsonData, UTF8_CHAR_SET)); } } // post.setEntity(new StringEntity(params[1], HTTP.UTF_8)); // post.setEntity(new UrlEncodedFormEntity(pair, HTTP.UTF_8)); response = httpClient.execute(post); } final int statusCode = response.getCode(); if (statusCode == HttpStatus.SC_OK) { // 处理cookie // 此处只需把之前提供的 cookieStore 对象拿到就可以获取cookie信息了 resultData.setCookiestore(cookieStore); HttpEntity entity = response.getEntity(); if(entity != null){ // 把接收到的字节解�? // byte[] result = FileCopyUtils.copyToByteArray(entity.getContent()); // byte[] decodeResult = this.getContentCoder().decrypt(result); //2015-07-29 增加压缩判断 李润冬,解压缩还未测�? byte[] result=FileCopyUtils.copyToByteArray(getInputStream(response, entity)); //解密 李润�?015-07-28 if(getContentCoder()!=null){ byte[] descrypt = getContentCoder().decrypt(result); // if(timeRecorder != null){ // timeRecorder.setDecryptTime(tester.getTotalTime()); // } resultData.setHtml(new String(descrypt)); }else{ resultData.setHtml(new String(result)); } return resultData; } else { return null; } } else if(methodOfPost){ post.abort(); logger.error("服务调用完成,但返回错误代码:" + statusCode); } else { get.abort(); logger.error("服务调用完成,但返回错误代码:" + statusCode); } return null; } catch(ClientProtocolException ce){ throw new RemoteAccessorException("httpClient协议错误", ce); } catch(IOException ioe){ throw new RemoteAccessorException("httpClient连接异常IO", ioe, true); } catch(Exception ex){ throw new RemoteAccessorException("httpClient请求转换结果错误:computeResult()", ex); } finally { } } @Override protected void responseEmpty() { logger.debug(".......同步http调用返回空数"); } private InputStream getInputStream(HttpResponse response, HttpEntity entity) throws Exception { InputStream is = entity.getContent(); boolean gzip = false; if (response.containsHeader("Content-Encoding")) {// [Content-Language: // zh-CN, // Content-Encoding: // gzip, // Content-Length: // 10, // Server: // Jetty(6.1.26)] String gzipStr = response.getHeaders("Content-Encoding")[0].getValue(); gzip = gzipStr.equals("gzip") ? true : false; } if (gzip) {// 头文件支持压,然后检查数据格式是否为GZIP压缩 BufferedInputStream bis = new BufferedInputStream(is); bis.mark(2); // 取前两个字节 byte[] header = new byte[2]; int result = bis.read(header); // reset输入流到位置 bis.reset(); // 判断是否是GZIP格式 int headerData = getShort(header); // Gzip �?的前两个字节�?0x1f8b if (result != -1 && headerData == 0x1f8b) { // DebugUtil.debug(TAG, " use GZIPInputStream "); is = new GZIPInputStream(bis); } else { // DebugUtil.debug(TAG, " not use GZIPInputStream"); is = bis; } } return is; } private int getShort(byte[] data) { return (int) ((data[0] << 8) | data[1] & 0xFF); } }