Преглед на файлове

Merge remote-tracking branch 'origin/4.0' into 4.0

4.0
郑根木 преди 2 години
родител
ревизия
a9c3ce1d19
променени са 3 файла, в които са добавени 469 реда и са изтрити 1 реда
  1. +10
    -0
      smtweb-framework/core/pom.xml
  2. +1
    -1
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java
  3. +458
    -0
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/HttpUtil.java

+ 10
- 0
smtweb-framework/core/pom.xml Целия файл

@@ -34,6 +34,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>


+ 1
- 1
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java Целия файл

@@ -6,7 +6,7 @@ package cc.smtweb.framework.core.common;
public interface SwConsts {
class SysParam {
//开发调试模式
public static final boolean SYS_DEBUG = true;
public static boolean SYS_DEBUG = true;
//系统启动完成
public static boolean SYS_STARTED = false;
//运行的项目,多个用半角逗号分隔


+ 458
- 0
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/HttpUtil.java Целия файл

@@ -0,0 +1,458 @@
package cc.smtweb.framework.core.util;

import cc.smtweb.framework.core.common.SwMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
* Created by Akmm at 2017/7/4 16:58
* http辅助类,支持http/https
*/
@Slf4j
public class HttpUtil {
private static final String HTTP = "http";
private static final String HTTPS = "https";
private static SSLConnectionSocketFactory sslsf = null;
private static PoolingHttpClientConnectionManager cm = null;
private static SSLContextBuilder builder = null;
private static RequestConfig requestConfig = null;

private static final Integer MAX_TOTAL = 200; //连接池最大连接数
private static final Integer MAX_PER_ROUTE = 100; //单个路由默认最大连接数
private static final Integer REQ_TIMEOUT = 10 * 1000; //请求超时时间ms
private static final Integer CONN_TIMEOUT = 10 * 1000; //连接超时时间ms
private static final Integer SOCK_TIMEOUT = 5 * 60 * 1000; //读取超时时间ms
private static HttpClientConnectionMonitorThread thread; //HTTP链接管理器线程


static {
try {
builder = new SSLContextBuilder();
// 全部信任 不做身份鉴定
builder.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
});
sslsf = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(HTTP, new PlainConnectionSocketFactory())
.register(HTTPS, sslsf)
.build();
cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(MAX_TOTAL);//max connection
cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
thread = new HttpClientConnectionMonitorThread(cm);

requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(REQ_TIMEOUT) //从连接池中获取连接的超时时间
//与服务器连接超时时间:httpclient会创建一个异步线程用以创建socket连接,此处设置该socket的连接超时时间
.setConnectTimeout(CONN_TIMEOUT)
.setSocketTimeout(SOCK_TIMEOUT) //socket读数据超时时间:从服务器获取响应数据的超时时间
.build();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* http调用
*
* @param url 请求地址
* @param paras 参数,name,value形式
* @return
* @throws Exception
*/
public static SwMap post(String url, String... paras) throws Exception {
SwMap map = new SwMap();
int n = 0;
while (n < paras.length) {
map.put(paras[n++], paras[n++]);
}
return post(url, map);
}

public static SwMap post(String url, Map<String, String> paras) throws Exception {
String json_resp = post(url, null, paras, null);
if (StringUtils.isEmpty(json_resp) || !json_resp.startsWith("{")) return null;
return (SwMap) JsonUtil.parseMap(json_resp);
}

/**
* Post 请求
*
* @param url 请求url
* @param paras json 格式参数
* @return
* @throws Exception
*/
public static SwMap post(String url, SwMap paras) throws Exception {
return post(url, paras, false);
}

/**
* Post 请求
*
* @param url 请求url
* @param paras json 参数
* @param encode json 是否加密传输
* @return
* @throws Exception
*/
public static SwMap post(String url, SwMap paras, boolean encode) throws Exception {
return post(url, paras, encode, null);
}

public static SwMap post(String url, SwMap paras, boolean encode, String charset) throws Exception {
if (StringUtils.isEmpty(charset)) charset = "UTF-8";
String param = JsonUtil.encodeString(paras);
if (encode) param = Base64.encodeBase64String(param.getBytes(charset));
StringEntity entity = new StringEntity(param, charset);//解决中文乱码问题
entity.setContentEncoding(charset);
entity.setContentType("application/json");
String json_resp = post(url, null, null, entity, charset);
if (encode && !json_resp.startsWith("{")) {//加密传输时,解密
json_resp = new String(Base64.decodeBase64(json_resp),charset);
}
if (StringUtils.isEmpty(json_resp) || !json_resp.startsWith("{")) return null;
return (SwMap)JsonUtil.parseMap(json_resp);
}

/**
* 加密请求
*
* @param url
* @param paras
* @param encode
* @return
* @throws Exception
*/
public static SwMap post(String url, Map<String, String> paras, boolean encode) throws Exception {
return post(url, paras, encode, null);
}

public static SwMap post(String url, Map<String, String> paras, boolean encode, String charset) throws Exception {
String json_resp = post(url, null, paras, null, charset);
if (encode) {
json_resp = new String(Base64.decodeBase64(json_resp),charset);
}
if (StringUtils.isEmpty(json_resp) || !json_resp.startsWith("{")) return null;
return (SwMap)JsonUtil.parseMap(json_resp);
}


public static SwMap post(String url,Map<String, String> header, Map<String, String> paras) throws Exception {
String json_resp = post(url, header, paras, null);
if (StringUtils.isEmpty(json_resp) || !json_resp.startsWith("{")) return null;
return (SwMap) JsonUtil.parseMap(json_resp);
}

/**
* httpClient post请求
*
* @param url 请求url
* @param header 头部信息
* @param param 请求参数 form提交适用
* @param entity 请求实体 json/xml提交适用
* @return 可能为空 需要处理
* @throws Exception
*/
public static String post(String url, Map<String, String> header, Map<String, String> param, HttpEntity entity) throws Exception {
return post(url, header, param, entity, null);
}
public static String post(String url, Map<String, String> header, Map<String, String> param, HttpEntity entity, String charset) throws Exception {
return postEx(url,header,param,entity,charset,null);
}
public static String postEx(String url, Map<String, String> header, Map<String, String> param, HttpEntity entity, String charset, Consumer<Header[]> headerWorker) throws Exception {
if (StringUtils.isEmpty(charset)) charset = "UTF-8";
String result = "";
CloseableHttpClient httpClient = null;
HttpResponse httpResponse = null;
try {
httpClient = getHttpClient();
HttpPost httpPost = getHttpPost(url);
// 设置头信息
if (header!=null && header.size()>0) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
}
// 设置请求参数
if (param!=null && param.size()>0) {
List<NameValuePair> formparams = new ArrayList<>();
for (Map.Entry<String, String> entry : param.entrySet()) {
//给参数赋值
formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(formparams, charset);
httpPost.setEntity(urlEncodedFormEntity);
}
// 设置实体 优先级高
if (entity != null) {
httpPost.setEntity(entity);
}
httpResponse = httpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
if(headerWorker!=null){
headerWorker.accept(httpResponse.getAllHeaders());
}
HttpEntity resEntity = httpResponse.getEntity();
result = EntityUtils.toString(resEntity, charset);
EntityUtils.consume(resEntity);
} else {
result = readHttpResponse(httpResponse);
}
} catch (Exception e) {
log.error("POST_ERROR:",e);
} finally {
if (httpClient != null) {
httpClient.close();
}
if (httpResponse != null) {
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
EntityUtils.consume(httpEntity);
}
}
}
return result;
}

/**
* httpClient post请求
*
* @param url 请求url
* @param header 头部信息
* @return 可能为空 需要处理
* @throws Exception
*/
public static String get(String url, Map<String, String> header) throws Exception {
String result = "";
CloseableHttpClient httpClient = null;
HttpResponse httpResponse = null;
try {
httpClient = HttpUtil.getHttpClient();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig);
// 设置头信息
if (header!=null && header.size()>0) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpGet.addHeader(entry.getKey(), entry.getValue());
}
}
httpResponse = httpClient.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
HttpEntity resEntity = httpResponse.getEntity();
result = EntityUtils.toString(resEntity);
EntityUtils.consume(resEntity);
} else {
result = readHttpResponse(httpResponse);
}
} finally {
if (httpClient != null) {
httpClient.close();
}
if (httpResponse != null) {
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
EntityUtils.consume(httpEntity);
}
}
}
return result;
}

public static CloseableHttpClient getHttpClient() throws Exception {
// thread = new HttpClientConnectionMonitorThread(cm);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.setConnectionManagerShared(true)
.disableAutomaticRetries() //关闭自动处理重定向
.setRedirectStrategy(new LaxRedirectStrategy())//利用LaxRedirectStrategy处理POST重定向问题
.setDefaultRequestConfig(requestConfig)
.build();

return httpClient;
}

public static HttpPost getHttpPost(String url) {
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
return httpPost;
}

private static String readHttpResponse(HttpResponse httpResponse)
throws ParseException, IOException {
StringBuilder builder = new StringBuilder();
// 获取响应消息实体
HttpEntity entity = httpResponse.getEntity();
// 响应状态
builder.append("status:" + httpResponse.getStatusLine());
builder.append("headers:");
HeaderIterator iterator = httpResponse.headerIterator();
while (iterator.hasNext()) {
builder.append("\t" + iterator.next());
}
// 判断响应实体是否为空
if (entity != null) {
String responseString = EntityUtils.toString(entity);
builder.append("response length:" + responseString.length());
builder.append("response content:" + responseString.replace("\r\n", ""));
}
return builder.toString();
}

public static void main(String[] args) throws Exception {


// //用线程池发送请求
// ExecutorService executor = Executors.newFixedThreadPool(3);
//
// Thread t1 = new Thread(new Runnable() {
// @Override
// public void run() {
// for (int i = 0; i < 100; i++) {
// HttpPost post = getHttpPost("http://127.0.0.1:8080/qhmz/receiveBankData.do");
// System.out.println("请求第【" + (i + 1) + "】次:【receiveBankData】");
// try {
// CloseableHttpClient httpclient = UtilHttp.getHttpClient();
// CloseableHttpResponse response2 = httpclient.execute(post);
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】,结果" + response2.getStatusLine());
// httpclient.close();
// EntityUtils.consume(response2.getEntity());
// } catch (Exception e) {
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】" + UtilPub.getOrigMsg(e));
// }
//
// }
// }
// });
// Thread t2 = new Thread(new Runnable() {
// @Override
// public void run() {
// for (int i = 0; i < 100; i++) {
// HttpPost post = getHttpPost("http://127.0.0.1:8080/qhmz/cust/ebank/biz/service.do");
// System.out.println("请求第【" + (i + 1) + "】次:【service】");
// try {
// CloseableHttpClient httpclient = UtilHttp.getHttpClient();
// CloseableHttpResponse response2 = httpclient.execute(post);
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】,结果" + response2.getStatusLine());
// httpclient.close();
// EntityUtils.consume(response2.getEntity());
// } catch (Exception e) {
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】" + UtilPub.getOrigMsg(e));
// }
//
// }
// }
// });
// Thread t3 = new Thread(new Runnable() {
// @Override
// public void run() {
// for (int i = 0; i < 100; i++) {
// HttpPost post = getHttpPost("http://127.0.0.1:8080/qhmz/cust/ebank/biz/isSupBank.do");
// System.out.println("请求第【" + (i + 1) + "】次:【isSupBank】");
// try {
// CloseableHttpClient httpclient = UtilHttp.getHttpClient();
// CloseableHttpResponse response2 = httpclient.execute(post);
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】,结果" + response2.getStatusLine());
// httpclient.close();
// EntityUtils.consume(response2.getEntity());
// } catch (Exception e) {
// System.out.println("请求第【" + (i + 1) + "】次:【" + post.getURI() + "】" + UtilPub.getOrigMsg(e));
// }
//
// }
// }
// });
// executor.execute(t1);
// executor.execute(t2);
// executor.execute(t3);
// executor.shutdown();
}

/**
* <p>Description: 使用管理器,管理HTTP连接池 无效链接定期清理功能</p>
*
* @author andy 2017年8月28日
*/
public static class HttpClientConnectionMonitorThread extends Thread {

private final HttpClientConnectionManager connManager;
private volatile boolean shutdown;

public HttpClientConnectionMonitorThread(HttpClientConnectionManager connManager) {
super();
this.setName("http-connection-monitor");
this.setDaemon(true);
this.connManager = connManager;
this.start();
}

@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000); // 等待5秒
// 关闭过期的链接
connManager.closeExpiredConnections();
// 选择关闭 空闲30秒的链接
connManager.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
}
}

/**
* 方法描述: 停止 管理器 清理无效链接 (该方法当前暂时关闭)
*
* @author andy 2017年8月28日 下午1:45:18
*/
@Deprecated
public void shutDownMonitor() {
synchronized (this) {
shutdown = true;
notifyAll();
}
}

}

}

Зареждане…
Отказ
Запис