前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊HttpClient的HttpRoutePlanner

聊聊HttpClient的HttpRoutePlanner

原创
作者头像
code4it
发布2023-10-16 09:01:52
2460
发布2023-10-16 09:01:52
举报
文章被收录于专栏:码匠的流水账

本文主要研究一下HttpClient的HttpRoutePlanner

HttpRoutePlanner

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

代码语言:javascript
复制
/**
 * 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.
 * <p>
 * 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.
 * </p>
 *
 * @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;

}

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

DefaultRoutePlanner

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

代码语言:javascript
复制
/**
 * 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;
    }

}

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

SchemePortResolver

org/apache/http/conn/SchemePortResolver.java

代码语言:javascript
复制
/**
 * 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;

}

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

DefaultSchemePortResolver

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

代码语言:javascript
复制
@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");
        }
    }

}

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

小结

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HttpRoutePlanner
  • DefaultRoutePlanner
  • SchemePortResolver
  • DefaultSchemePortResolver
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档