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<T> extends RemoteSyncTask<T> {
|
|
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<String, String> simpleData, String url, String jsonData
|
, String methodType, String contentType, Map<String, String> 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<NameValuePair> 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<String, String> header, HttpUriRequestBase request){
|
if(header != null){
|
for(Map.Entry<String, String> entry : header.entrySet()){
|
request.setHeader(entry.getKey(), entry.getValue());
|
}
|
}
|
}
|
|
@Override
|
protected String requestForData(Map<String, String> 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<NameValuePair> 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<String, Object> 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<String, String> 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<NameValuePair> 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);
|
}
|
|
}
|