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);
        }
      
    }
  • 相关阅读:
    Thinkphp3.2.3如何加载自定义函数库
    mysql 字段引号那个像单引号的撇号用法
    php cli模式学习(PHP命令行模式)
    Django model 表与表的关系
    Django model 字段详解
    Django model 中的字段解释
    python系列-1 字符串操作
    nginx-匹配规则
    ansible系列3-pyYAML
    ansible系列2-常用命令
  • 原文地址:https://www.cnblogs.com/gisblogs/p/5594001.html
Copyright © 2011-2022 走看看