实际使用client的过程中,会遇到一种情况,如cookie的Key为空的,此时默认的cookie的策略处理cookie是会报错。

这时咱可以通过重写cookiestore策略来解决如:

    /**
     * @description 自定义Cookie策略
     *
     * @title  setCustomCookieSpec
     * @param builder
     * @return void
     */
    private static void setCustomCookieSpec(HttpClientBuilder builder) {

    CookieSpecProvider easySpecProvider = new CookieSpecProvider() {

        public org.apache.http.cookie.CookieSpec create(HttpContext context) {

            return new BrowserCompatSpec() {
                public void validate(Cookie cookie, CookieOrigin origin)
                        throws MalformedCookieException {
                }

                protected List<Cookie> parse(final HeaderElement[] elems,
                        final CookieOrigin origin)
                        throws MalformedCookieException {
                    final List<Cookie> cookies = new ArrayList<Cookie>(
                            elems.length);
                    for (final HeaderElement headerelement : elems) {
                        final String name = headerelement.getName();
                        final String value = headerelement.getValue();
                        if (value == null) {
                            continue;
                        }
                        if (name == null || name.length() == 0) {
                            throw new MalformedCookieException(
                                    "Cookie name may not be empty");
                        }

                        final BasicClientCookie cookie = new BasicClientCookie(
                                name, value);
                        cookie.setPath(getDefaultPath(origin));
                        cookie.setDomain(getDefaultDomain(origin));

                        // cycle through the parameters
                        final NameValuePair[] attribs = headerelement
                                .getParameters();
                        for (int j = attribs.length - 1; j >= 0; j--) {
                            final NameValuePair attrib = attribs[j];
                            final String s = attrib.getName().toLowerCase(
                                    Locale.ENGLISH);

                            cookie.setAttribute(s, attrib.getValue());

                            final CookieAttributeHandler handler = findAttribHandler(s);
                            if (handler != null) {
                                handler.parse(cookie, attrib.getValue());
                            }
                        }
                        cookies.add(cookie);
                    }
                    return cookies;
                }

            };
        }

    };
    Registry<CookieSpecProvider> r = RegistryBuilder
            .<CookieSpecProvider> create()
            .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
            .register(CookieSpecs.BROWSER_COMPATIBILITY,
                    new BrowserCompatSpecFactory())
            .register("easy", easySpecProvider).build();
    builder.setDefaultCookieSpecRegistry(r);
}

最后上个完整的代码:

package com.lkb.manager.httpclient;

import java.io.IOException;
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.List;
import java.util.Locale;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;

import org.apache.http.HeaderElement;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.CookieSpecs;
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.ConnectionKeepAliveStrategy;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieAttributeHandler;
import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.cookie.BestMatchSpecFactory;
import org.apache.http.impl.cookie.BrowserCompatSpec;
import org.apache.http.impl.cookie.BrowserCompatSpecFactory;
import org.apache.http.protocol.HttpContext;

import com.lkb.manager.util.LogUtil;
import com.lkb.manager.util.SpiderUtil;

public class HttpClientUtil {

    /**
    * @Fields CURRENT_HTTP_CLIENT_CONTEXT : httpclient 上下文
    */
    private static final String HTTP_CLIENT_CONTEXT = "HttpClientUtil.HtppClientContext";

    /**
    * @Fields CURRENT_HTTP_CLIENT : httpclient
    */
    public static final String HTTP_CLIENT = "HttpClientUtil.HttpClient";

    public static CloseableHttpClient HttpClient(){
        CloseableHttpClient client = (CloseableHttpClient)SpiderUtil.getSessions().get(HTTP_CLIENT);
         if(client==null){
             client = HttpClientUtil.getHttpClient();
             SpiderUtil.getSessions().put(HTTP_CLIENT, client);
         }
         return client;
    }
    public static HttpClientContext HttpClientContext(){
        HttpClientContext context = (HttpClientContext)SpiderUtil.getSessions().get(HTTP_CLIENT_CONTEXT);
        if(context==null){
            context = HttpClientContext.create();
            SpiderUtil.getSessions().put(HTTP_CLIENT_CONTEXT, context);
        }
        return context;
    }

    public static CloseableHttpClient getHttpClient(){
        CloseableHttpClient client = null;
        for (int i = 0; i < 2; i++) {
            try{
                 HttpClientBuilder builder = createSSLClientDefault();
                 setCustomCookieSpec(builder);//cookie 策略
                 setExecutionCount(builder);
                 setKeepAliveDuration(builder);
                 client = builder.build();
            }catch(Exception e){
                e.printStackTrace();
            }
            if(client!=null){
                return client;
            }
        }
        LogUtil.error(null,"HttpClient初始化失败!");
        return null;
    }

    /**
     * https通用策略
     * @Title: createSSLClientDefault
     * @return HttpClientBuilder 返回类型
     * @throws
     */
    private static HttpClientBuilder createSSLClientDefault(){
        try {
             SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                 //信任所有
                 public boolean isTrusted(X509Certificate[] chain,
                                 String authType) throws CertificateException {
                     return true;
                 }
             }).build();
             SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
             return HttpClients.custom().setSSLSocketFactory(sslsf);
             } catch (KeyManagementException e) {
                 e.printStackTrace();
             } catch (NoSuchAlgorithmException e) {
                 e.printStackTrace();
             } catch (KeyStoreException e) {
                 e.printStackTrace();
             }
             return  null;
        } 

    /**
     * @description 自定义Cookie策略
     *
     * @title  setCustomCookieSpec
     * @param builder
     * @return void
     */
    private static void setCustomCookieSpec(HttpClientBuilder builder) {

    CookieSpecProvider easySpecProvider = new CookieSpecProvider() {

        public org.apache.http.cookie.CookieSpec create(HttpContext context) {

            return new BrowserCompatSpec() {
                public void validate(Cookie cookie, CookieOrigin origin)
                        throws MalformedCookieException {
                }

                protected List<Cookie> parse(final HeaderElement[] elems,
                        final CookieOrigin origin)
                        throws MalformedCookieException {
                    final List<Cookie> cookies = new ArrayList<Cookie>(
                            elems.length);
                    for (final HeaderElement headerelement : elems) {
                        final String name = headerelement.getName();
                        final String value = headerelement.getValue();
                        if (value == null) {
                            continue;
                        }
                        if (name == null || name.length() == 0) {
                            throw new MalformedCookieException(
                                    "Cookie name may not be empty");
                        }

                        final BasicClientCookie cookie = new BasicClientCookie(
                                name, value);
                        cookie.setPath(getDefaultPath(origin));
                        cookie.setDomain(getDefaultDomain(origin));

                        // cycle through the parameters
                        final NameValuePair[] attribs = headerelement
                                .getParameters();
                        for (int j = attribs.length - 1; j >= 0; j--) {
                            final NameValuePair attrib = attribs[j];
                            final String s = attrib.getName().toLowerCase(
                                    Locale.ENGLISH);

                            cookie.setAttribute(s, attrib.getValue());

                            final CookieAttributeHandler handler = findAttribHandler(s);
                            if (handler != null) {
                                handler.parse(cookie, attrib.getValue());
                            }
                        }
                        cookies.add(cookie);
                    }
                    return cookies;
                }

            };
        }

    };
    Registry<CookieSpecProvider> r = RegistryBuilder
            .<CookieSpecProvider> create()
            .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
            .register(CookieSpecs.BROWSER_COMPATIBILITY,
                    new BrowserCompatSpecFactory())
            .register("easy", easySpecProvider).build();
    builder.setDefaultCookieSpecRegistry(r);
}

    /**
     * 默认请求次数
     * @param builder
     */
    private static void setExecutionCount(HttpClientBuilder builder){
        HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

            public boolean retryRequest(
                    IOException exception,
                    int executionCount,
                    HttpContext context) {
                if (executionCount >= 4) {
                    // 如果已经重试了5次,就放弃
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    // 超时
                    return false;
                }
                if (exception instanceof UnknownHostException) {
                    // 目标服务器不可达
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {
                    // 连接被拒绝
                    return false;
                }
                if (exception instanceof SSLException) {
                    // ssl握手异常
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // 如果请求是幂等的,就再次尝试
                    return true;
                }
                return false;
            }

        };
        builder.setRetryHandler(myRetryHandler);
    }
    /**关闭连接*/
    public static void colse(){
        try {
            CloseableHttpClient c = (CloseableHttpClient) SpiderUtil.getSessions().get(HttpClientUtil.HTTP_CLIENT);
            if(c!=null){
                c.close();
            }
        } catch (IOException e) {
            LogUtil.error(e,"HttpClient关闭失败");
        }
    }

    private  static void setKeepAliveDuration(HttpClientBuilder builder){
         ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {
                @Override
                public long getKeepAliveDuration(
                    HttpResponse response,
                    HttpContext context) {
                        long keepAlive = super.getKeepAliveDuration(response, context);
                        if (keepAlive == -1) {
                            //如果服务器没有设置keep-alive这个参数,我们就把它设置成5秒
                            keepAlive = 4000;
                        }
                        return keepAlive;
                }

            };
            //定制我们自己的httpclient
            builder.setKeepAliveStrategy(keepAliveStrat);
    }

}

HttpClient_自定义cookie策略的更多相关文章

  1. python urllib2 支持 自定义cookie

    先是在GOOGLE 上找了下, 发现就是只有2种方法,试了下,果然不行. 1, MozillaCookieJar 自定义保存到文件中 加载的时候不行,保存没问题. 2,opener.addheader ...

  2. HttpClient

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且 ...

  3. HttpClient,DefaultHttpClient使用详解

    HttpClient:是一个接口 首先需要先创建一个DefaultHttpClient的实例 HttpClient httpClient=new DefaultHttpClient(); 发送GET请 ...

  4. HttpClient模拟http请求

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且 ...

  5. 接口测试之HttpClient

    HttpClient使用详解   Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客 ...

  6. 网络请求框架----HttpClient的get,post和图片上传服务器

    HttpClient是Apache Jakarta Common下的子项目,用来提供高效的.最新的.功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议.HttpCli ...

  7. 转载:HttpClient使用详解

    原文地址:http://blog.csdn.net/wangpeng047/article/details/19624529 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自 ...

  8. HttpClient_HttpClient 4.3.6 HTTP状态管理

    HTTP状态管理 最初的HTTP被设计成以状态.请求/应答为导向的协议,它被制作成是没有特殊条款的,以便在状态会话中能交换逻辑关系请求/应答.HTTP协议越来越受欢迎和被采用,越来越多的系统会在应用程 ...

  9. Apache HttpClient

    HpptClient特性 1. 基于标准.纯净的java语言.实现了Http1.0和Http1.1 2. 以可扩展的面向对象的结构实现了Http全部的方法(GET, POST, PUT, DELETE ...

随机推荐

  1. C#如何在PDF文件添加图片印章

    文档中添加印章可以起一定的作用,比如,防止文件随意被使用,或者确保文档内容的安全性和权威性.C#添加图片印章其实也有很多实现方法,这里我使用的是免费的第三方软件Free Spire.PDF,向大家阐述 ...

  2. MD5加密

    public string Second_MD5(string str) { MD5 md5 = MD5.Create();//创建MD5实例 byte[] strbyte = Encoding.UT ...

  3. oracle11g interval(numtoyminterval())自动创建表分区

    Oracle11g通过间隔分区实现按月创建表分区 在项目数据库设计过程中由于单表的数据量非常庞大,需要对表进行分区处理.由于表中的数据是历史交易,故按月分区,提升查询和管理. 由于之前对于表分区了解不 ...

  4. SVN 使用锁实现独占式签出

      SVN默认并行工作,但是自动合并又做得很渣.团队工作中,如果确实有一些文件希望独占式签出可以使用SVN的特别属性.       Subversion针对此问题的解决方案是提供一种机制,提醒用户在开 ...

  5. JAVA 8 函数式接口 - Functional Interface

    什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ...

  6. Codeforces Round #250 (Div. 2) C、The Child and Toy

    注意此题,每一个部分都有一个能量值v[i],他移除第i部分所需的能量是v[f[1]]+v[f[2]]+...+v[f[k]],其中f[1],f[2],...,f[k]是与i直接相连(且还未被移除)的部 ...

  7. 为什么C#不使用多继承?(from stackoverflow)

    简单地说:是因为该语言的设计者决定不使用. 基本上,.NET和Java的设计者不使用多继承(MI),是因为他们认为给语言加上多继承获得的好处较少,抵不上因此增加的复杂性. 1.不同的语言对于多继承如何 ...

  8. Visual Studio 2015 各版本神KEY

    Visual Studio 2015 简体中文专业版专业版神Key:HMGNV-WCYXV-X7G9W-YCX63-B98R2 Visual Studio 2015 繁体中文企业版企业版神Key1:H ...

  9. 鸟哥的linux私房菜学习记录之账号管理与权限设定

    每个登录者都会取到两个ID,一个使用者ID,一个群组ID

  10. YII2.0中实现高级注册

    如何在不修改逻辑代码的情况下完美解决以上三个问题?看了下面的教程,一目了然! 以高级版2.0.6为例,打开/frontend/models/SignupForm.php class SignupFor ...