• HttpClient 4.3 使用


    httpclient的api变化很快,本篇随笔记录自己使用4.3.6版本时所做的设置。版本虽然不是最新,但达到了目的就行。

    maven依赖:

    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.6</version>
    </dependency>


    请求设置的方法:
    //4.3版本不设置超时的话,一旦服务器没有响应,等待时间N久(>24小时)
    RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(20000) //建立连接超时时间
       .setSocketTimeout(
    10000) //获取数据超时 .setConnectionRequestTimeout(10000) //从连接池中取出的时间 .setCookieSpec(CookieSpecs.BEST_MATCH) //cookie的识别方式,还有浏览器兼容、标准方式、不管理使用cookie等方式
      .build();

    在使用时发现如果将cookieSpec设置为标准可能会提示识别不了XSRF-TOKEN等cookie,而使用最佳匹配没有问题。

    设置支持https请求:

    private SSLConnectionSocketFactory getSSLSF(){
            SSLContextBuilder builder = new SSLContextBuilder();
    //        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            try {
                builder.loadTrustMaterial(null, new TrustStrategy(){
                    public boolean isTrusted(X509Certificate[] chain, String authType)
                            throws CertificateException {
                        return true;
                    }
                });
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }
            SSLConnectionSocketFactory sslsf = null;
            try {
                sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            return sslsf;
        }
    //httpClient.setSSLSocketFactory(sslsf)或者通过连接管理器来设置
    setConnectionManager(使用下面的代码给连接池管理器设置使用http/https)
    private PoolingHttpClientConnectionManager getConnectionManager(SSLConnectionSocketFactory sslsf){ Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new PlainConnectionSocketFactory()) .register("https", sslsf) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); //org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool //出现大量上述异常不是连接池不够大,可能是maxPerRoute的值太小了,或者是没有释放资源,The fix is, the response entity need to be consumed. cm.setMaxTotal(2000);//max connection cm.setDefaultMaxPerRoute(200);//该值默认较小,表示对每个目标地址的连接数不超过200//(目前只有一个路由,因此可以让他等于最大值) //另外设置http client的重试次数,默认是3次;当前是禁用掉(如果项目用不到,这个默认即可) //httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false)); //cm.closeExpiredConnections(); return cm; }

    设置httpclient可随时切换代理地址

    client.setRoutePlanner (HttpRoutePlanner routePlanner)

    public class DynamicProxyRoutePlanner implements HttpRoutePlanner {
        private DefaultRoutePlanner planner = null;
    
        /**
         * @param host 为null时不使用代理
         */
        public DynamicProxyRoutePlanner(HttpHost host){
            if(host==null){
                planner=new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE);
            }else
                planner = new DefaultProxyRoutePlanner(host);
        }
    
        /**
         * change proxy
         * @param host apply null for not using proxy
         */
        public void setProxy(HttpHost host){
            if(host==null){
                planner=new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE);
            }else
                planner = new DefaultProxyRoutePlanner(host);
        }
        //Override 接口中的方法实现
        public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
            return planner.determineRoute(target, request, context);
        }
    }

    切换代理时使用routePlanner.setProxy(httpHost);

    控制CookieStore

    你也许想对cookie进行持久存储,或做更多的控制,可以通过实现CookieStore接口或继承BasicCookieStore。

    如获取cookie字符串:

    public class MyCookieStore extends BasicCookieStore{
        //用于在setHeader中整个替换,向服务器发送的cookie只包括键和值而不包括失效日期等。
        @Override
        public synchronized String toString() {
            StringBuilder builder = new StringBuilder();
    
            for (Cookie c :super.getCookies())
            {
                builder.append(c.getName()).append("=")
                        .append(c.getValue()).append("; ");
            }
            if(builder.length()==0) return null;
            return builder.substring(0,builder.length()-2).toString();
        }
    }

    转成JSON格式的字符串,用于保存和恢复:

    //先写一个类用于转换,使用了FastJSON (你可以换成其他的工具)
    public class CookieMapper {
        public Cookie toCookie(JSONObject jsonObject) throws JSONException {
            BasicClientCookie2 cookie = new BasicClientCookie2(jsonObject.getString("name"), jsonObject.getString("value"));
            cookie.setComment(jsonObject.getString("comment"));
            cookie.setCommentURL(jsonObject.getString("commentURL"));
            cookie.setDomain(jsonObject.getString("domain"));
            cookie.setPath(jsonObject.getString("path"));
            cookie.setSecure(jsonObject.getBooleanValue("secure"));
            cookie.setVersion(jsonObject.getIntValue("version"));
            Long timeLong=jsonObject.getLong("expiryDate");
            if(timeLong != null)//注意getLong返回的对象可能为空,而getLongValue可以返回0
                cookie.setExpiryDate(new Date(timeLong));
            if (jsonObject.containsKey("ports")) {
                cookie.setPorts(JSONArrayToArray(jsonObject.getJSONArray("ports")));
            }
            return cookie;
        }
    
        public JSONObject toJSONObject(Cookie cookie) throws JSONException {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", cookie.getName());
            jsonObject.put("value", cookie.getValue());
            jsonObject.put("comment", cookie.getComment());
            jsonObject.put("commentURL", cookie.getCommentURL());
            jsonObject.put("domain", cookie.getDomain());
            jsonObject.put("path", cookie.getPath());
            jsonObject.put("secure", cookie.isSecure());
            jsonObject.put("version", cookie.getVersion());
            if (cookie.getExpiryDate() != null) {
                jsonObject.put("expiryDate", cookie.getExpiryDate().getTime());
            }
            if (cookie.getPorts() != null) {
                JSONArray jsonArray = arrayToJSONArray(cookie.getPorts());
                jsonObject.put("ports", jsonArray);
            }
            return jsonObject;
        }
    
        private JSONArray arrayToJSONArray(int[] ports) {
            JSONArray jsonArray = new JSONArray();
            for(int i = 0 ; i < ports.length; i++){
                jsonArray.add(ports[i]);
            }
            return jsonArray;
        }
    
        private int[] JSONArrayToArray(JSONArray jsonArray) throws JSONException {
            int size=jsonArray.size();
            int[] ports = new int[size];
            for(int i = 0 ; i < size; i++){
                ports[i] = jsonArray.getInteger(i);
            }
            return ports;
        }
    
    }

    使用下面的方法对Cookie与String进行相互转换:

    private String toJsonString(List<Cookie> cookies) {
            CookieMapper cookieMapper = new CookieMapper();
            try {
                JSONArray jsonArray = new JSONArray();
                for (Cookie cookie1 : cookies) {
                    jsonArray.add(cookieMapper.toJSONObject(cookie1));
                }
                return jsonArray.toString();
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    private Cookie[] getCookiesFromStore(String jsonStr) {
            if (jsonStr==null || jsonStr.equals("")) {
                return new Cookie[0];
            }
            CookieMapper cookieMapper = new CookieMapper();
            try {
                    JSONArray jsonArray = JSONArray.parseArray(jsonStr);
                    List<Cookie> cookies = new ArrayList<Cookie>(jsonArray.size());
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        cookies.add(cookieMapper.toCookie(jsonObject));
                    }
                    return cookies.toArray(new Cookie[0]);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
        }
    client.setDefaultCookieStore来设置httpclient使用自己的cookieStore

  • 相关阅读:
    MySQL Thread Pool: Problem Definition
    MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析
    Mysql源码目录结构
    android学习18——对PathMeasure中getPosTan的理解
    android学习17——命令行建gradle工程
    android学习16——library project的使用
    android学习13——android egl hello world
    ant编译java的例子
    android学习12——重载SurfaceView一些方法的执行顺序
    Visual Studio命令行创建库文件lib
  • 原文地址:https://www.cnblogs.com/makefile/p/5375601.html
Copyright © 2020-2023  润新知