HttpClient_自定义cookie策略

实际使用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);
    }
  
}
原文地址:https://www.cnblogs.com/gisblogs/p/5594001.html