聊聊HttpClient的NoHttpResponseException

代码探幽鹤
• 阅读 249

本文主要研究一下HttpClient的NoHttpResponseException

NoHttpResponseException

org/apache/http/NoHttpResponseException.java

/**
 * Signals that the target server failed to respond with a valid HTTP response.
 *
 * @since 4.0
 */
public class NoHttpResponseException extends IOException {

    private static final long serialVersionUID = -7658940387386078766L;

    /**
     * Creates a new NoHttpResponseException with the specified detail message.
     *
     * @param message exception message
     */
    public NoHttpResponseException(final String message) {
        super(HttpException.clean(message));
    }

}
NoHttpResponseException继承了IOException,用于表示目标服务器没有返回一个正常的http response

DefaultHttpResponseParser

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

public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {

    private final Log log = LogFactory.getLog(getClass());

    private final HttpResponseFactory responseFactory;
    private final CharArrayBuffer lineBuf;

    //......

    @Override
    protected HttpResponse parseHead(
            final SessionInputBuffer sessionBuffer) throws IOException, HttpException {
        //read out the HTTP status string
        int count = 0;
        ParserCursor cursor = null;
        do {
            // clear the buffer
            this.lineBuf.clear();
            final int i = sessionBuffer.readLine(this.lineBuf);
            if (i == -1 && count == 0) {
                // The server just dropped connection on us
                throw new NoHttpResponseException("The target server failed to respond");
            }
            cursor = new ParserCursor(0, this.lineBuf.length());
            if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) {
                // Got one
                break;
            } else if (i == -1 || reject(this.lineBuf, count)) {
                // Giving up
                throw new ProtocolException("The server failed to respond with a " +
                        "valid HTTP response");
            }
            if (this.log.isDebugEnabled()) {
                this.log.debug("Garbage in response: " + this.lineBuf.toString());
            }
            count++;
        } while(true);
        //create the status line from the status string
        final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
        return this.responseFactory.newHttpResponse(statusline, null);
    }

    protected boolean reject(final CharArrayBuffer line, final int count) {
        return false;
    }
}    
DefaultHttpResponseParser继承了AbstractMessageParser,其parseHead方法读取sessionBuffer,若该数据为空则抛出NoHttpResponseException("The target server failed to respond")

小结

NoHttpResponseException继承了IOException,用于表示目标服务器没有返回一个正常的http response,一般是目标服务器负载太高处理不过来因而断开了连接,也有可能是目标服务器把这个空闲连接关闭了,而HttpClient则继续用这个连接发送请求则会读取不到正常的reponse,因而抛出NoHttpResponseException。大多数情况下,可以通过重试解决。另外针对因为keep-alive超时断开的,可以配置HttpClient的connTimeToLive值小于服务端的keepAlive值(通常是60s)。

doc

点赞
收藏
评论区
推荐文章
待兔 待兔
4年前
Dart 源码分析:深入理解 dart:io HttpClient
HttpClient  HttpClient(https://links.jianshu.com/go?tohttps%3A%2F%2Fapi.dartlang.org%2Fstable%2F2.4.1%2Fdartio%2FHttpClientclass.html)是DartSDK中提供的标准的访问网络的接口类,是
待兔 待兔
4年前
Dart 源码分析:深入理解 dart:io HttpClient
HttpClient  HttpClient(https://links.jianshu.com/go?tohttps%3A%2F%2Fapi.dartlang.org%2Fstable%2F2.4.1%2Fdartio%2FHttpClientclass.html)是DartSDK中提供的标准的访问网络的接口类,是
Stella981 Stella981
4年前
HttpClient 连接池配置和使用
在游戏项目开发中,经常会向其它的服务发送一些Http请求,获取一些数据或验证。比如充值,SDK验证等。如果每次都重新创建一个新的HttpClient对象的话,当并发上来时,容易出现异常或连接失败,超时。这里可以使用HttpClient的连接池配置,减少HttpClient创建的数量,减少资源开销。packagecom.mygame.common
Wesley13 Wesley13
4年前
Java之HttpClient调用WebService接口发送短信源码实战
摘要Java之HttpClient调用WebService接口发送短信源码实战一:接口文档!Java之HttpClient调用WebService接口源码001.png(https://imgblog.csdnimg.cn/img_convert/1e2ea7858d12c11af36e591290ba0496.png)
Wesley13 Wesley13
4年前
Java中httpClient中的三种超时设置总结
在Apache的HttpClient包中,有三个设置超时的地方:/\从连接池中取连接的超时时间\/ConnManagerParams.setTimeout(params,1000);/_连接超时_/HttpConnectionParams.setConnectionTimeout(params,2000);/_请求超时_/HttpCon
Stella981 Stella981
4年前
AsyncTask
import java.io.ByteArrayOutputStream;import java.io.InputStream;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apac
Stella981 Stella981
4年前
HttpClient 实现 socks 代理
HttpClient实现socks代理使用的环境<dependency<groupIdorg.apache.httpcomponents</groupId<artifactIdhttpclient</artifactId<version4.4.1</version</dependency
Stella981 Stella981
4年前
HttpClient使用总结
<divclass"htmledit\_views"<h1<aname"t0"</a一、使用方法</h1<p使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。<br1.创建HttpClient对象。<br2.创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需
Wesley13 Wesley13
4年前
Voovan开发指南 (三) HttpClient开发
HttpClient特点介绍VoovanHttpClient是基于Voovan开源项目的异步通信开发,兼容Http1.1协议的Http通信客户端工具,支持标准的HTTP1.1协议及HTTPS。本文将引导大家如何快速的使用HttpClient连续的访问一个网址.特点:基于Voovan
Wesley13 Wesley13
4年前
HttpClient 4.3超时设置
HttpClient4.3。HttpClient这货和Lucene一样,每个版本的API都变化很大,这有点让人头疼。就好比创建一个HttpClient对象吧,每一个版本的都不一样,3.X是这样的?(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.openopen.com
Stella981 Stella981
4年前
HttpClient
接着上一篇(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.jianshu.com%2Fp%2Ff38a62efaa96),总结一下HttpClient发送https请求相关的内容。先简单介绍连接工厂(interfaceorg.apache.http.conn.sock