昨夜,甘肃临夏州积石山县发生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://www.cnblogs.com/buguge/p/17914514.html