zoukankan      html  css  js  c++  java
  • 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);
        }
      
    }
  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/gisblogs/p/5594001.html
Copyright © 2011-2022 走看看