最近项目上需要用到企业微信应用进行消息的群发功能,用来将系统产生的告警消息通过企业微信群发的方式通知客户方,来达到及时处理故障的目的,使用了下还是较简单的,这里记录一下过程,备查。文章前面有一点术语的介绍,如果想快速直接看怎么使用,点击这里跳过基本术语介绍,直接开始。

一.基本术语介绍说明

1.corpid

每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID”(需要有管理员权限)
在这里插入图片描述

2.userid

每个成员都有唯一的userid,即所谓“帐号”。在管理后台->“通讯录”->点进某个成员的详情页,可以看到。
在这里插入图片描述

3.部门id

每个部门都有唯一的id,在管理后台->“通讯录”->“组织架构”->点击某个部门右边的小圆点可以看到
在这里插入图片描述

4.tagid

每个标签都有唯一的标签id,在管理后台->“通讯录”->“标签”,选中某个标签,在右上角会有“标签详情”按钮,点击即可看到
在这里插入图片描述
在这里插入图片描述

5.agentid

每个应用都有唯一的agentid。在管理后台->“应用与小程序”->“应用”,点进某个应用,即可看到agentid。
在这里插入图片描述

6.secret

secret是企业应用里面用于保障数据安全的“钥匙”,每一个应用都有一个独立的访问密钥,为了保证数据的安全,secret务必不能泄漏。

自建应用secret。在管理后台->“应用与小程序”->“应用”->“自建”,点进某个应用,即可看到。
基础应用secret。某些基础应用(如“审批”“打卡”应用),支持通过API进行操作。在管理后台->“应用与小程序”->“应用->”“基础”,点进某个应用,点开“API”小按钮,即可看到。
通讯录管理secret。在“管理工具”-“通讯录同步”里面查看(需开启“API接口同步”);
客户联系管理secret。在“客户联系”栏,点开“API”小按钮,即可看到。

7.access_token

access_token是企业后台去企业微信的后台获取信息时的重要票据,由corpid和secret产生。所有接口在通信时都需要携带此信息用于验证接口的访问权限

二.通过企业微信服务端API群发应用消息

1.Http接口调用工具类准备

因为需要用到Http调用,这里提前准备2个Http的调用工具,一个是Java的Jdk自带实现的,不依赖任何jar包,可用于测试,如果你的调用量不多,也可以用于生产。另一个是依赖apache的httpClient,具备连接池功能,建议可用于生产。因为代码占内容太多,因此代码位于文章最后,可直接跳转至代码部署查看,点击即会跳转

2.获取access_token

官方接口文档:https://work.weixin.qq.com/api/doc/90000/90135/91039
请求方式:GET(HTTPS)
请求URL:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
在这里插入图片描述
注:通常正式环境需要自己登陆后自行维护access_token,一般是2小时有效期,在快到期或已过期时需要重新登陆,可以用利用返回结果码为40014和42001分别表示为非法access_token和过期的access_token,可以利用此两个错误码进行判断与更新

测试代码:
使用纯Jdk实现的工具类进行调试:

	public static void main(String[] args) throws Exception {
		
		String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww160d****&corpsecret=BAtr2B***************";
		HttpRestUtils util = new HttpRestUtils();
		String result = util.doGet(url);
		System.out.println(result);
		
	}

或者使用apache的httpClient的工具类调试:

	public static void main(String[] args) throws InterruptedException {
		//这里把你的corpid和corpsecret替换成正确的
		String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww160d****&corpsecret=BAtr2B***************";
		System.out.println(HttpsKit.get(url));

		//关闭连接池,正式环境中这个不要关闭
		HttpsKit.closeConnectionPool();
		
	}

响应接果:

{"errcode":0,"errmsg":"ok","access_token":"vMpg1HNU8PHf0qqNSfVGMXw2Gg0HN16LnvMH3J4LXeoY5MMA25PiO2ZabcdHJ6bRi5PqUuyLf94aRBb3yTKs344h5eU35doprLeIKtuf9xfKOk8VQ6F_GeTuxmcV_qQH0CLOrc5y9cXT9SCEi7LpQCiS4F4ssdff0zu-jyGmlEtUBplqSF8xDQBJ3aj6-hfg","expires_in":7200}

3.调用群应用消息发送接口即可

群应用消息发送接口官方文档:https://work.weixin.qq.com/api/doc/90000/90135/90236
应用支持推送文本、图片、视频、文件、图文等类型。
请求方式:POST(HTTPS)
请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN

以文本消息为例,access_token在请求地址里面,其他的参数就是以json方式封装,其他的参数可参看详情的上面的文档获取。比如以下截图即从官方文档中获取到的
在这里插入图片描述
测试代码如下:
使用纯Jdk实现的工具类进行调试:

	public static void main(String[] args) throws Exception {
		
		String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=JhLKJB2cZssssssssssssssssssssssssssssssssssssU2HHQ";
		HttpRestUtils util = new HttpRestUtils();
		String paramStr = "{\"touser\":\"@all\",\"msgtype\":\"text\",\"agentid\":1000001,\"text\":{\"content\":\"测试下应用群发告警消息,打扰了,请忽略。\"}}";
		String result = util.doPost(url, paramStr);
		System.out.println(result);
		
	}

或者使用apache的httpClient的工具类调试:

	public static void main(String[] args) throws InterruptedException {
		
		String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=JhLKJB2cZssssssssssssssssssssssssssssssssssssU2HHQ";
		String data = "{\"touser\":\"@all\",\"msgtype\":\"text\",\"agentid\":1000001,\"text\":{\"content\":\"测试下应用群发告警消息,打扰了,请忽略。\"}}";
		System.out.println(HttpsKit.postJson(url, data));
		
		//关闭连接池,正式环境中这个不要关闭
		HttpsKit.closeConnectionPool();
		
	}

4.Http接口调用工具类代码提供如下

工具类1:使用纯jdk自带的URLConnection实现的

package cn.gzsendi.system.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpRestUtils {
	
	private final String GET = "GET";
	private final String POST = "POST";
	private final String CharacterSet = "UTF-8";
	
	public String doGet(String url) throws Exception{
		String method = this.GET;
		return load(url,null,method);
	}
	
	public String doPost(String url, String params) throws Exception{
		String method = this.POST;
		return load(url,params,method);
	}
	
	/**
	 * @param url
	 * @param params
	 * @param method
	 * @return
	 * @throws Exception
	 */
	public String load(String url,String params,String method) throws Exception {
		
		HttpURLConnection conn = null;
		
		try {
			
			boolean isHttps = url.startsWith("https");
			
			URL restURL = new URL(url);
			conn = (HttpURLConnection) restURL.openConnection();	
			
			//https请求需要格外处理下
			if(isHttps) {
				
				TrustManager[] tm = { new MyX509TrustManager() };
			    SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			    sslContext.init(null, tm, new java.security.SecureRandom());
			    SSLSocketFactory ssf = sslContext.getSocketFactory();
			    ((HttpsURLConnection)conn).setSSLSocketFactory(ssf);
			    ((HttpsURLConnection)conn).setHostnameVerifier(new TrustAnyHostnameVerifier());
				
			}
			
			conn.setDoOutput(true);
			conn.setAllowUserInteraction(false);
			conn.setUseCaches(false); 
			conn.setRequestMethod(method);
			conn.connect();
			
			OutputStreamWriter out = null;
			OutputStream outputStream = null;
			if(this.POST.equals(method) && params != null){
				outputStream = conn.getOutputStream();
				out = new OutputStreamWriter(outputStream, this.CharacterSet);
				out.write(params);
				out.close();
			}
			
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, this.CharacterSet);
			BufferedReader bReader = new BufferedReader(inputStreamReader);
			String line = "";
			
			StringBuffer resultStr = new StringBuffer();
			while (null != (line = bReader.readLine())) {
				resultStr.append(line);
			}
			
			// 释放资源
			bReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			if(out!=null) out.close();
			if(outputStream!=null)outputStream.close();
			
			return resultStr.toString();
			
		} catch (Exception e) {
			
			e.printStackTrace();
			
		} finally {
			if(conn != null) conn.disconnect();
		}
		
		return null;
		
	}
	
	private class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            // 直接返回true
            return true;
        }
    }
	
	private class MyX509TrustManager implements X509TrustManager {

		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			
		}

		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}

}

工具类2:使用apache的httpclient进行编写实现类
注:pom依赖,我的工具类里面用到了common-io,httpclient,和log4j,其中log4j如果你不想要,可以根据代码进行调整删除,common-io也是一样,也可以采用其他方法,修改点代码就可。

		<!-- httpclient start -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.12</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpmime</artifactId>
			<version>4.5.12</version>
		</dependency>
		<!-- httpclient end -->
	
		<!-- common-io start -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.7</version>
		</dependency>
		<!-- common-io end -->
		
		<!-- log start -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.25</version>
		</dependency>

		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
		<!-- log end -->
package cn.gzsendi.system.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;

import org.apache.commons.codec.CharEncoding;
import org.apache.commons.io.IOUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
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.conn.ssl.TrustStrategy;
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.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsKit {

	private static Logger logger = LoggerFactory.getLogger(HttpsKit.class);
	private static final int CONNECT_TIMEOUT = 10000;// 设置连接建立的超时时间为10000ms
	private static final int SOCKET_TIMEOUT = 30000; // 多少时间没有数据传输
	private static final int HttpIdelTimeout = 30000;//空闲时间
	private static final int HttpMonitorInterval = 10000;//多久检查一次
	private static final int MAX_CONN = 200; // 最大连接数
	private static final int Max_PRE_ROUTE = 200; //设置到路由的最大连接数,
	private static CloseableHttpClient httpClient; // 发送请求的客户端单例
	private static PoolingHttpClientConnectionManager manager; // 连接池管理类
	private static ScheduledExecutorService monitorExecutor;
	
	private static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
	private static final String APPLICATION_JSON = "application/json";

	private final static Object syncLock = new Object(); // 相当于线程锁,用于线程安全
	
	private static RequestConfig requestConfig = RequestConfig.custom()
			.setConnectionRequestTimeout(CONNECT_TIMEOUT)
			.setConnectTimeout(CONNECT_TIMEOUT)
			.setSocketTimeout(SOCKET_TIMEOUT).build();

	private static CloseableHttpClient getHttpClient() {

		if (httpClient == null) {
			// 多线程下多个线程同时调用getHttpClient容易导致重复创建httpClient对象的问题,所以加上了同步锁
			synchronized (syncLock) {
				if (httpClient == null) {
					
					try {
						httpClient = createHttpClient();
					} catch (KeyManagementException e) {
						logger.error("error",e);
					} catch (NoSuchAlgorithmException e) {
						logger.error("error",e);
					} catch (KeyStoreException e) {
						logger.error("error",e);
					}
					
					// 开启监控线程,对异常和空闲线程进行关闭
					monitorExecutor = Executors.newScheduledThreadPool(1);
					monitorExecutor.scheduleAtFixedRate(new TimerTask() {
						@Override
						public void run() {
							
							// 关闭异常连接
							manager.closeExpiredConnections();
							
							// 关闭5s空闲的连接
							manager.closeIdleConnections(HttpIdelTimeout,TimeUnit.MILLISECONDS);
							
							logger.info(manager.getTotalStats().toString());
							//logger.info("close expired and idle for over "+HttpIdelTimeout+"ms connection");
						}
						
					}, HttpMonitorInterval, HttpMonitorInterval, TimeUnit.MILLISECONDS);
				}
			}
		}
		return httpClient;
	}

	/**
	 * 构建httpclient实例
	 * @return
	 * @throws KeyStoreException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 */
	private static CloseableHttpClient createHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
		
		SSLContextBuilder builder = new SSLContextBuilder();
        // 全部信任 不做身份鉴定
        builder.loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                return true;
            }
        });
		
		ConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
		LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
		Registry<ConnectionSocketFactory> registry = RegistryBuilder
				.<ConnectionSocketFactory> create()
				.register("http", plainSocketFactory)
				.register("https", sslSocketFactory).build();

		manager = new PoolingHttpClientConnectionManager(registry);
		// 设置连接参数
		manager.setMaxTotal(MAX_CONN); // 最大连接数
		manager.setDefaultMaxPerRoute(Max_PRE_ROUTE); // 路由最大连接数

		// 请求失败时,进行请求重试
		HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {
			
			@Override
			public boolean retryRequest(IOException e, int i,	HttpContext httpContext) {
				
				if (i > 3) {
					// 重试超过3次,放弃请求
					logger.error("retry has more than 3 time, give up request");
					return false;
				}
				if (e instanceof NoHttpResponseException) {
					// 服务器没有响应,可能是服务器断开了连接,应该重试
					logger.error("receive no response from server, retry");
					return true;
				}
				if (e instanceof SSLHandshakeException) {
					// SSL握手异常
					logger.error("SSL hand shake exception");
					return false;
				}
				if (e instanceof InterruptedIOException) {
					// 超时
					logger.error("InterruptedIOException");
					return false;
				}
				if (e instanceof UnknownHostException) {
					// 服务器不可达
					logger.error("server host unknown");
					return false;
				}
				if (e instanceof ConnectTimeoutException) {
					// 连接超时
					logger.error("Connection Time out");
					return false;
				}
				if (e instanceof SSLException) {
					logger.error("SSLException");
					return false;
				}

				HttpClientContext context = HttpClientContext.adapt(httpContext);
				HttpRequest request = context.getRequest();
				
				if (!(request instanceof HttpEntityEnclosingRequest)) {
					// 如果请求不是关闭连接的请求
					return true;
				}
				return false;
			}
		};

		CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).setRetryHandler(handler).build();
		return client;
	}

	public static String get(String url) {
		
		HttpGet httpGet = new HttpGet(url);
		httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
		httpGet.setConfig(requestConfig);
		
		CloseableHttpResponse response = null;
		InputStream in = null;

		String result = null;
		
		try {
			
			response = getHttpClient().execute(httpGet,HttpClientContext.create());
			
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				in = entity.getContent();
				result = IOUtils.toString(in, "utf-8");
			}
			
		} catch (IOException e) {
			logger.error("error",e);
		} finally {
			try {
				if (in != null) in.close();
			} catch (IOException e) {
				logger.error("error",e);
			}
			
			try {
				if (response != null) response.close();
			} catch (IOException e) {
				logger.error("error",e);
			}
		}
		
		return result;
	}
	
	public static String postJson(String url,Map<String,Object> requestParams) {
		return postJson(url, JsonUtil.toJSONString(requestParams));
	}
	
	public static String postJson(String url,Map<String,Object> requestParams,Map<String,Object> headerParams) {
		return postJson(url, JsonUtil.toJSONString(requestParams),headerParams);
	}
	
	public static String postJson(String url,String requestParamStr) {
		return postJson(url, requestParamStr, null);
	}
	
	public static String postJson(String url,String requestParamStr,Map<String,Object> headerParams) {
		
		HttpPost httppost = new HttpPost(url);
		
		httppost.setHeader("Content-Type", APPLICATION_JSON+";charset=" + CharEncoding.UTF_8);
        httppost.setHeader("Accept",APPLICATION_JSON+";charset=" +CharEncoding.UTF_8);
        httppost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
        
        if(headerParams != null && headerParams.size()>0){
        	for(String headerName : headerParams.keySet()) {
        		httppost.setHeader(headerName,headerParams.get(headerName)+"");
            }
        }
        
        StringEntity se = new StringEntity(requestParamStr,CharEncoding.UTF_8);
        se.setContentType(APPLICATION_JSON+";charset=" +CharEncoding.UTF_8);
        httppost.setEntity(se);
        
        httppost.setConfig(requestConfig);
		
		CloseableHttpResponse response = null;
		InputStream in = null;

		String result = null;
		
		try {
			
			response = getHttpClient().execute(httppost,HttpClientContext.create());
			
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				in = entity.getContent();
				result = IOUtils.toString(in, "utf-8");
			}
			
		} catch (IOException e) {
			logger.error("error",e);
		} finally {
			try {
				if (in != null) in.close();
			} catch (IOException e) {
				logger.error("error",e);
			}
			
			try {
				if (response != null) response.close();
			} catch (IOException e) {
				logger.error("error",e);
			}
		}
		
		return result;
	}
	
	//requestParamStr---------->>> name=test&age=12
	public static String postFormUrlencoded(String url,String requestParamStr) {
		return postFormUrlencoded(url, requestParamStr ,null);
		
	}
	
	public static String postFormUrlencoded(String url,String requestParamStr,Map<String,Object> headerParams) {
		Map<String,String> requestParams = new HashMap<String,String>();
		
		String[] strs = requestParamStr.split("&");
		for(String str : strs) {
			String[] keyValues = str.split("=");
			if(keyValues.length == 2) {
				requestParams.put(keyValues[0], keyValues[1]);
			}
		}
		
		return postFormUrlencoded(url, requestParams,headerParams);
		
	}
	
	public static String postFormUrlencoded(String url,Map<String,String> requestParams) {
		return postFormUrlencoded(url,requestParams,null);
	}
	
	public static String postFormUrlencoded(String url,Map<String,String> requestParams,Map<String,Object> headerParams) {
		
		HttpPost httppost = new HttpPost(url);
		
		//application/json
		httppost.setHeader("Content-Type", APPLICATION_FORM_URLENCODED+";charset=" + CharEncoding.UTF_8);
        httppost.setHeader("Accept",APPLICATION_FORM_URLENCODED+";charset=" +CharEncoding.UTF_8);
        httppost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
        
        if(headerParams != null && headerParams.size()>0){
        	for(String headerName : headerParams.keySet()) {
        		httppost.setHeader(headerName,headerParams.get(headerName)+"");
            }
        }
        
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        
        for(String keyStr : requestParams.keySet()) {
            formparams.add(new BasicNameValuePair(keyStr, requestParams.get(keyStr)));
        }
        
        UrlEncodedFormEntity uefe = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        httppost.setEntity(uefe);
        
        httppost.setConfig(requestConfig);
		
		CloseableHttpResponse response = null;
		InputStream in = null;

		String result = null;
		
		try {
			
			response = getHttpClient().execute(httppost,HttpClientContext.create());
			
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				in = entity.getContent();
				result = IOUtils.toString(in, "utf-8");
			}
			
		} catch (IOException e) {
			logger.error("error",e);
		} finally {
			try {
				if (in != null) in.close();
				if (response != null) response.close();
			} catch (IOException e) {
				logger.error("error",e);
			}
		}
		
		return result;
		 
	}

	/**
	 * 关闭连接池
	 */
	public static void closeConnectionPool() {
		try {
			if(httpClient != null) httpClient.close();
			if(manager != null) manager.close();
			if(monitorExecutor != null) monitorExecutor.shutdown();
		} catch (IOException e) {
			logger.error("error",e);
		}
	}
}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐