• 聊聊HttpClient的HttpRoutePlanner


    本文主要研究一下HttpClient的HttpRoutePlanner

    HttpRoutePlanner

    org/apache/http/conn/routing/HttpRoutePlanner.java

    /**
     * Encapsulates logic to compute a {@link HttpRoute} to a target host.
     * Implementations may for example be based on parameters, or on the
     * standard Java system properties.
     * 

    * Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. *

    * * @since 4.0 */ public interface HttpRoutePlanner { /** * Determines the route for a request. * * @param target the target host for the request. * Implementations may accept {@code null} * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param context the context to use for the subsequent execution. * Implementations may accept {@code null}. * * @return the route that the request should take * * @throws HttpException in case of a problem */ HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    HttpRoutePlanner接口定义了determineRoute方法,用于决定该请求的目标route

    DefaultRoutePlanner

    org/apache/http/impl/conn/DefaultRoutePlanner.java

    /**
     * Default implementation of an {@link HttpRoutePlanner}. It will not make use of
     * any Java system properties, nor of system or browser proxy settings.
     *
     * @since 4.3
     */
    @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
    public class DefaultRoutePlanner implements HttpRoutePlanner {
    
        private final SchemePortResolver schemePortResolver;
    
        public DefaultRoutePlanner(final SchemePortResolver schemePortResolver) {
            super();
            this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
                DefaultSchemePortResolver.INSTANCE;
        }
    
        @Override
        public HttpRoute determineRoute(
                final HttpHost host,
                final HttpRequest request,
                final HttpContext context) throws HttpException {
            Args.notNull(request, "Request");
            if (host == null) {
                throw new ProtocolException("Target host is not specified");
            }
            final HttpClientContext clientContext = HttpClientContext.adapt(context);
            final RequestConfig config = clientContext.getRequestConfig();
            final InetAddress local = config.getLocalAddress();
            HttpHost proxy = config.getProxy();
            if (proxy == null) {
                proxy = determineProxy(host, request, context);
            }
    
            final HttpHost target;
            if (host.getPort() <= 0) {
                try {
                    target = new HttpHost(
                            host.getHostName(),
                            this.schemePortResolver.resolve(host),
                            host.getSchemeName());
                } catch (final UnsupportedSchemeException ex) {
                    throw new HttpException(ex.getMessage());
                }
            } else {
                target = host;
            }
            final boolean secure = target.getSchemeName().equalsIgnoreCase("https");
            return proxy == null
                            ? new HttpRoute(target, local, secure)
                            : new HttpRoute(target, local, proxy, secure);
        }
    
        /**
         * This implementation returns null.
         *
         * @throws HttpException may be thrown if overridden
         */
        protected HttpHost determineProxy(
                final HttpHost target,
                final HttpRequest request,
                final HttpContext context) throws HttpException {
            return null;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    DefaultRoutePlanner实现了HttpRoutePlanner接口,其determineRoute方法在host的port小于等于0时通过schemePortResolver.resolve来确定port

    SchemePortResolver

    org/apache/http/conn/SchemePortResolver.java

    /**
     * Strategy for default port resolution for protocol schemes.
     *
     * @since 4.3
     */
    public interface SchemePortResolver {
    
        /**
         * Returns the actual port for the host based on the protocol scheme.
         */
        int resolve(HttpHost host) throws UnsupportedSchemeException;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    SchemePortResolver接口定义了resolve方法,用于根据协议来返回真正的port

    DefaultSchemePortResolver

    org/apache/http/impl/conn/DefaultSchemePortResolver.java

    @Contract(threading = ThreadingBehavior.IMMUTABLE)
    public class DefaultSchemePortResolver implements SchemePortResolver {
    
        public static final DefaultSchemePortResolver INSTANCE = new DefaultSchemePortResolver();
    
        @Override
        public int resolve(final HttpHost host) throws UnsupportedSchemeException {
            Args.notNull(host, "HTTP host");
            final int port = host.getPort();
            if (port > 0) {
                return port;
            }
            final String name = host.getSchemeName();
            if (name.equalsIgnoreCase("http")) {
                return 80;
            } else if (name.equalsIgnoreCase("https")) {
                return 443;
            } else {
                throw new UnsupportedSchemeException(name + " protocol is not supported");
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    DefaultSchemePortResolver方法针对http返回80,针对https返回443,其他的抛出UnsupportedSchemeException

    小结

    HttpClient的HttpRoutePlanner接口定义了determineRoute方法,用于决定该请求的目标route;DefaultRoutePlanner实现了HttpRoutePlanner接口,其determineRoute方法在host的port小于等于0时通过schemePortResolver.resolve来确定port(http返回80,https返回443)。

  • 相关阅读:
    EPC在新能源光伏电站的优势和功能流程
    国外LEAD赚钱,做个网站真的很简单
    1.ts介绍
    使用列表实现向量运算
    Spring框架(中)
    算法竞赛入门【码蹄集新手村600题】(MT1301-1350)
    如何搭建“Docker Registry私有仓库,在CentOS7”?
    springboot悠悠转二手网站毕业设计源码181134
    python中使用sqlalchemy操作数据库遇到密码包含@的处理方法
    深入探讨梯度下降:优化机器学习的关键步骤(一)
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/133851095