HttpClient (CloseableHttpclient) 如果通过连接池管理 通过cookie保持状态值JSESSIONID 自行保持会话分别处理同一会话中的请求.如 匿名登录 验证码 验证码校验 登录等。
处理方式完全可以用连接池去管理httpClient 从而省去不少问题。但是最近测试给我的反应是验证码明明输入正确 但却返回验证码不正确 信息。 总结 原因 很可能是因为 会话未保持。由于时间关系 没精力去分析httpClient 连接池的管理机制,只好自己写了 类似的管理器去存储管理。。。当然这里还有优化的地方 比如获取的时候可以通过spring cache 注解的方式去获取httpClient 无序做过多逻辑判断。代码如下:
package com.yuntai.yun.online.util.http; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by hurd on 2015/12/20. * 获取httpclient 工厂类 */ public class HttpClientFactory { private static final Logger logger = LoggerFactory.getLogger(HttpClientFactory.class); Map<String,HttpClientBody> map = new HashMap<>(); private int expire = 3600; public HttpClient create(String unicode) { HttpClientBody body = map.get(unicode); if(body == null){ body = new HttpClientBody(HttpClientBuilder.create().build(),new Date()); map.put(unicode,body); }else{ Date expireDate = body.getTimestamp(); if(((new Date().getTime() - expireDate.getTime())/1000 -expire) > 0){ logger.info("session过期重新创建"); try { body.getHttpClient().close(); } catch (IOException e) { e.printStackTrace(); } body = new HttpClientBody(HttpClientBuilder.create().build(),new Date()); map.put(unicode,body); }else{ body.setTimestamp(new Date()); } } return body.getHttpClient(); } /** * 定时任务执行 清楚无效的httplient */ public void taskInit(){ for(String key : map.keySet()){ HttpClientBody body = map.get(key); if(body != null){ CloseableHttpClient httpClient = body.getHttpClient(); Date expireDate = body.getTimestamp(); if(new Date().getTime() - expireDate.getTime() - expire*1000 < 0){ continue; } try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } logger.info("待删除无效的httpClient,key:{},HttpClientBody:{}",key,map.get(key)); //删除过期或者无效的 httpclient map.remove(key); } logger.info("-----------定时任务清理完成------------"); } public void setExpireTimeSeconds(int time){ expire = time; } /** * 内部类 */ private class HttpClientBody { private CloseableHttpClient httpClient; public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } private Date timestamp; public HttpClientBody(CloseableHttpClient httpClient, Date timestamp) { this.httpClient = httpClient; this.timestamp = timestamp; } public CloseableHttpClient getHttpClient() { return httpClient; } public Date getTimestamp() { return timestamp; } } }
package com.yuntai.yun.online.util.http; import com.alibaba.fastjson.JSON; import com.yuntai.med.exception.MedRuntimeException; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; 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.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by hurd on 2015/12/20. */ public class RestHttpClient { private static final Logger logger = LoggerFactory.getLogger(RestHttpClient.class); @Autowired private HttpClientFactory clientFactory; /** * http client get请求封装 * * @param unicode * @param URL * @param headMap * @return */ public Map<String, ?> doGet(String unicode, String URL, Map<String, ?> headMap) { HttpClient httpClient = clientFactory.create(unicode); //创建httpGet方法 HttpGet httpGet = new HttpGet(URL); logger.info("准备执行httpget请求,uri={}", httpGet.getURI()); try { //设置头参数 if (null != headMap && !headMap.isEmpty()) { int len = headMap.size(); Header[] headers = new Header[len]; for (Map.Entry<String, ?> entry : headMap.entrySet()) { headers[--len] = new BasicHeader(entry.getKey(), entry.getValue().toString()); } } //执行http请求返回结果 HttpResponse response = httpClient.execute(httpGet); //返回响应状态 int status = response.getStatusLine().getStatusCode(); logger.info("返回响应状态:" + status); if (200 != status) { logger.info("httpGet请求执行失败,响应消息:{}", response); throw new RuntimeException("httpGet请求失败,请检查网络或者重试"); } //获取响应消息 HttpEntity entity = response.getEntity(); String content = EntityUtils.toString(entity, "UTF-8"); logger.info("获取的响应消息:" + content); return JSON.parseObject(content, Map.class); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("httpGet请求失败,请检查网络或者重试"); } } /** * http post 请求封装 * * @param unicode * @param URL * @param headMap * @param bodyMap * @return */ public <T> T doPost(String unicode, String URL, Map<String, ?> headMap, Map<String, ?> bodyMap, Class<T> clazz) { HttpClient httpClient = clientFactory.create(unicode); //创建httppost方法 HttpPost httpPost = new HttpPost(URL); boolean isJSON = false; logger.info("准备执行httppost请求,uri={},请求参数:{}", httpPost.getURI(), bodyMap); try { //设置头参数 if (null != headMap && !headMap.isEmpty()) { int len = headMap.size(); Header[] headers = new Header[len]; for (Map.Entry<String, ?> entry : headMap.entrySet()) { headers[--len] = new BasicHeader(entry.getKey(), entry.getValue().toString()); if ("Content-Type".equals(entry.getKey()) && ContentType.APPLICATION_JSON.getMimeType().equals(entry.getValue())) { isJSON = true; } } httpPost.setHeaders(headers); } //设置body参数 StringEntity stringEntity = null; if (isJSON) { stringEntity = new StringEntity(JSON.toJSONString(bodyMap)); stringEntity.setContentType("text/json"); stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); } else { if (null != bodyMap && !bodyMap.isEmpty()) { List<NameValuePair> formparams = new ArrayList<>(); for (Map.Entry<String, ?> entry : bodyMap.entrySet()) { formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); } stringEntity = new UrlEncodedFormEntity(formparams, "utf-8"); } } if (null != stringEntity) { httpPost.setEntity(stringEntity); } /* HttpClientContext context = HttpClientContext.create(); if(!StringUtil.isEmpty(jsessionId)){ logger.info("会话凭证 JSESSIONID=" + jsessionId); Registry<CookieSpecProvider> registry = RegistryBuilder.<CookieSpecProvider>create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()).build(); context.setCookieSpecRegistry(registry); CookieStore cookieStore = new BasicCookieStore(); cookieStore.addCookie(new BasicClientCookie("JSESSIONID",jsessionId)); context.setCookieStore(cookieStore); }*/ //执行http请求返回结果 HttpResponse response = httpClient.execute(httpPost); //返回响应状态 int status = response.getStatusLine().getStatusCode(); logger.info("返回响应状态:" + status); if (200 != status) { logger.info("httpGet请求执行失败,响应消息:{}", response); throw new RuntimeException("httpGet请求失败,请检查网络或者重试"); } //设置上下文会话信息 logger.info("@#$####"+ToStringBuilder.reflectionToString(response.getAllHeaders())); //获取响应消息 HttpEntity entity = response.getEntity(); //默认返回字节数组byte[] if (null != clazz) { if (byte[].class.equals(clazz)) { return (T) EntityUtils.toByteArray(entity); } if (String.class.equals(clazz)) { return (T) EntityUtils.toString(entity); } return JSON.parseObject(EntityUtils.toString(entity), clazz); } throw new MedRuntimeException("4001", "返回值不允许为空"); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("httpGet请求失败,请检查网络或者重试"); } } }