深入理解HttpClient

Httpclient的设计图:

   深入理解HttpClient

HttpClient请求过程:

从Request发起,经过DelegatingHanlder处理后,进入InnerHandler,数据返回后再从Inner Handler 返回到Delegating Hanlder进行处理,最后返回结果。

从设计角度来讲,HttpClient库提供了强大的扩展性,使用者不需要任何继承即可完成对HttpClient的扩展(如果对设计模式熟悉,可以清楚的看出这里用到了装饰器模式)

先看案例:

LoggingHandler:将HttpClient请求、响应内容记录日志

public class LoggingHandler : DelegatingHandler
    {
        public LoggingHandler(HttpMessageHandler handler) : base(handler) { }
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.Content!=null)
            {
                Debug.WriteLine(await request.Content.ReadAsStringAsync());
            }
            HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
            if (response.Content!=null)
            {
                Debug.WriteLine(await response.Content.ReadAsStringAsync());
            }
            return response;
        }
    }
HttpMessageHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(new LoggingHandler(handler));

代码说明:

1、HttpClient这个类本身并不会进行实际的网络请求收发处理,我们应将其理解成一个容器、一个中继者,实际的网络请求核心在HttpClientHanlder中,也就是前面图中对应的Inner Handler。

2、我们自己定义了一个LoggingHandler,这个类对应Delegating Handler 是我们自定义的、装饰在Inner Handler外的Handler

3、DelegatingHandler重载了SendAsync,在其内部调用了InnerHandler的SendAsync方法,如此我们便可以在实际请求发出,以及返回后进行各种统一的处理,总结起来仍是上面图中画出的,逐层调用。

4、HttpClientHandler、DelegatingHandler都是继承自HttpMessageHandler

HttpClientHandler:

public class HttpClientHandler : HttpMessageHandler
{}

DelegatingHandler:

public abstract class DelegatingHandler : HttpMessageHandler
{}

案例2:封装一个RetryHandler,目的是失败重试

RetryHandler:

public class RetryHandler : DelegatingHandler
    {
        private const int MAX_COUNT = 3;
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            HttpResponseMessage response = null;
            for (int i = 0; i < MAX_COUNT; i++)
            {
                response = await base.SendAsync(request, cancellationToken);
                if (response.IsSuccessStatusCode)
                {
                    return response;
                }
            }
            return response;
            
        }
    }
HttpMessageHandler handler = new HttpClientHandler();
handler = new LoggingHandler(handler);
handler = new RetryHandler(handler);
HttpClient client = new HttpClient(handler);

在.NET Core中,如果使用HttpClientFactory创建HttpClient,如何添加HttpMessageHandler?

需要自己去实现接口IHttpMessageHandlerBuilderFilter

参考:https://blog.csdn.net/weixin_30236595/article/details/101066107

...