昨夜,甘肃临夏州积石山县发生6.2级地震,影响到甘肃、青海地区。截至目前,已有100多人遇难。百度了一下当地天气,还挺冷,夜间温度低到-15℃。
时间就是生命,祈祷难民尽快得到救援!
分享今天解决的一个生产问题告警。
如下HTTP工具类中的httpClientPost方法使用apache的HttpClient(maven坐标:org.apache.httpcomponents:httpclient:4.5.12)发送POST请求。当传入的url参数非法时(如为null、为空串、不是有效的http地址),在执行client.execute方法时,程序会抛出异常“ProtocolException: Target host is not specified”。
public static CloseableHttpClient client;
static {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIME_OUT)
.setConnectionRequestTimeout(30000)
.build();
client = HttpClients.custom()
.setMaxConnPerRoute(50)
.setMaxConnTotal(200)
.setDefaultRequestConfig(requestConfig)
.setKeepAliveStrategy((response, context) -> 15 * 1000) // 设置Keepalive的时间为60s→2023-9-11 尝试规避NoHttpResponseException,与红洁/海鹏沟通,改为<60s
.build();
}
public static String httpClientPost(String url, Map<String, Object> params, String charset, int connectTimeout, int socketTimeout) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).setConnectionRequestTimeout(30000)
.build();
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
...
httpPost.setEntity(entity);
HttpResponse response = client.execute(httpPost);
// 读取服务器响应数据
return getHttpResult(response.getEntity().getContent(), charset);
}
异常stacktrace:
org.apache.http.client.ClientProtocolException
at com.emax.channel.provider.modules.serviceprovider.util.HttpClientHelper.httpClientPost(HttpClientHelper.java:393)
at com.emax.channel.provider.modules.serviceprovider.util.HttpClientHelper.main(HttpClientHelper.java:758)
Caused by: org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.emax.channel.provider.modules.serviceprovider.util.HttpClientHelper.httpClientPost(HttpClientHelper.java:389)
... 1 more
Caused by: org.apache.http.ProtocolException: Target host is not specified
at org.apache.http.impl.conn.DefaultRoutePlanner.determineRoute(DefaultRoutePlanner.java:71)
at org.apache.http.impl.client.InternalHttpClient.determineRoute(InternalHttpClient.java:125)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
... 4 more
因此,程序应先校验url参数的合法性,然后再执行http请求。
改造后的httpClientPost方法如下。
public static String httpClientPost(String url, Map<String, Object> params, String charset, int connectTimeout, int socketTimeout) {
if (StringUtils.isBlank(url)) {
throw new IllegalArgumentException("请求地址为空");
}
if (!url.toLowerCase().startsWith("http")) {
throw new IllegalArgumentException("请求地址非法");
}
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).setConnectionRequestTimeout(30000)
.build();
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
...
httpPost.setEntity(entity);
try {
HttpResponse response = client.execute(httpPost);
// 读取服务器响应数据
return getHttpResult(response.getEntity().getContent(), charset);
} catch (Exception e) {
Throwable cause = e.getCause();
//单独处理“Caused by: org.apache.http.ProtocolException: Target host is not specified”,转换成人话
if (cause instanceof org.apache.http.ProtocolException) {
// System.out.println("-----------------"+ cause.getMessage());Target host is not specified
throw new RuntimeException("请确保正确设置了目标主机的URL");
}
throw new RuntimeException(e);
}
}
标签:http,Target,java,httpPost,host,client,ProtocolException,apache,org From: https://blog.51cto.com/u_15708799/8985240