由于:java.io.IOException:HTTP/1.1 头部解析器未接收到任何字节

huangapple go评论73阅读模式
英文:

Caused by: java.io.IOException: HTTP/1.1 header parser received no bytes

问题

我第一次收到以下错误消息:
> Caused by: java.io.IOException: HTTP/1.1 头部解析器未接收到任何字节

(到目前为止,我的应用似乎都在工作...)

HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest
        .newBuilder()
        .GET()
        .uri(URI.create("..."))
        .header("Content-Type", "application/json")
        .build();

System.out.print(httpRequest.toString()); // 调试 - 没问题

HttpResponse<String> response = null;
try {
    response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

if (response != null && response.statusCode() == 200) {
    JSONObject jsonObject = new JSONObject(response.body());
    JSONArray jsonArray = jsonObject.getJSONArray("data");
    ObjectMapper objectMapper = ObjectMapperCreator.getNewObjectMapper();
    try {
        if (jsonArray.length() > 0) {
            correctlyCaught = true;
            return objectMapper.readValue(jsonArray.get(0).toString(), GeocodingResponse.class);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这是代码。为什么会出现这个错误?

英文:

I am getting for the first time
> Caused by: java.io.IOException: HTTP/1.1 header parser received no bytes

(my app seemed to work up to now...)

HttpClient httpClient = HttpClient.newHttpClient();
            HttpRequest httpRequest = HttpRequest
                    .newBuilder()
                    .GET()
                    .uri(URI.create(&quot;...&quot;))
                    .header(&quot;Content-Type&quot;, &quot;application/json&quot;)
                    .build();

            System.out.print(httpRequest.toString()); // dbg - it&#39;s ok

            HttpResponse&lt;String&gt; response = null;
            try {
                response = httpClient.send(httpRequest,
                        HttpResponse.BodyHandlers.ofString());
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }

            if (response != null &amp;&amp; response.statusCode() == 200) {
                JSONObject jsonObject = new JSONObject(response.body());
                JSONArray jsonArray = jsonObject.getJSONArray(&quot;data&quot;);
                ObjectMapper objectMapper = ObjectMapperCreator.getNewObjectMapper();
                try {
                    if (jsonArray.length() &gt; 0) {
                        correctlyCaught = true;
                        return objectMapper.readValue(jsonArray.get(0).toString(), GeocodingResponse.class);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

this is the code. Why am I getting this error?

答案1

得分: 13

HTTP 头部是服务器将会响应的第一件事

而该错误表示头部是空的。实际上,这个错误松散地翻译过来就是:“服务器什么都没有发送回来,然后挂断了”。

这也解释了为什么“之前它是工作的”。不是你的问题,是那台服务器的问题。它可能是损坏了、离线了,或者已经更新或替换,以至于无法再处理你的请求。

这+其他相关的 Stack Overflow 回答建议你强制使用 HTTP/1.1 模式 - 你只是在调整请求的发送方式,希望你能够塑造它,使得服务器不会因此而出错。最有可能的情况是服务器只是离线了,你只需要等一段时间或与管理员联系。还可以尝试使用类似 curl 或者你的浏览器连接到这个 URL,看看发生了什么。

另一个常见的原因是他们可能刚刚将他们的 HTTP(非 HTTPS 部分)下线了,或者它挂了,但是没人注意到,因为几乎没人*再使用 HTTP 连接。那么解决方法很可能就是在那个 URL 前面加一个's'。浏览器会通过各种机制将 http:// 的 URL 静默地升级为 https:// 的 URL,但是 Java 的 HTTP 库不会这样做,除非你明确要求(通过将那个 URL 改为 https)。所以,检查一下那个 URL(它没有出现在粘贴的文本中):如果是 http://,可以考虑改为 https:// 试试。

只是一个旁注:

} catch (IOException | InterruptedException e) {
               e.printStackTrace();
           }
           if (response != null && response.statusCode() == 200) {

请不要这样做。你在这里写的是:如果发生错误,不适当地记录下来(syserr 不是一个适合记录事物的地方),然后悄无声息地什么都不做。这会导致你以后可能会追踪错误,最终失败。请为自己着想。立刻进入你的 IDE,找到配置自动补全模板的地方。摒弃那个毫无用处、令人讨厌的 e.printStackTrace(),改为 throw new RuntimeException("未捕获的异常", e);。当发生你未处理的情况时,你最不希望的是“悄无声息地什么都不做”。你希望崩溃,并带有适当的堆栈跟踪信息。

英文:

The HTTP header is the very first thing that the server will respond with.

And that error says that it is empty. In effect then, this error, loosely translated, means: "The server sent absolutely nothing back and hung up".

This also explains why 'it worked before'. It's not you; it's that server. It's broken, offline, or has been updated or replaced so that it can no longer deal with your request.

This + other linked SO answers suggest you force HTTP/1.1 mode - you're just massaging how you send your request in the hope that you can shape it so that the server doesn't choke on it. Most likely the server is just offline and all you have to do is wait a while or get in contact with the administrator. Also try connecting to the URL with e.g. curl or your browser to see what's going on.

Another common reason for this is that they just took their HTTP (as in, the non-HTTPS side) offline or it died and nobody noticed because nobody* connects with HTTP anymore. Then the fix is probably to just.. toss an 's' in that URL. Browsers silently upgrade http:// urls into https:// urls via various mechanisms all the time, but java HTTP libraries don't do that unless you explicitly ask for it (by making that url https based). So, check that URL (it's not in the paste): If it's http://, consider trying again with https:// instead.

Just a sidenote:

>
&gt; } catch (IOException | InterruptedException e) {
&gt; e.printStackTrace();
&gt; }
&gt; if (response != null &amp;&amp; response.statusCode() == 200) {
&gt;

Please, don't do this. What you've written here is: If an error occurs, log it inappropriately (syserr is not an appropriate place to log things) and then silently do nothing. You're setting yourself up for wild goose chases and failure down the road. Do yourself a favour. Go into your IDE, right now, find the place where you configure autocompletion templates. And get rid of that useless, cringe inducing e.printStackTrace() and make that throw new RuntimeException(&quot;Uncaught&quot;, e);. When things occurs that you did not bother to handle, the last thing you'd want is 'silently do nothing'. You WANT the crash with the appropriate stack trace.

答案2

得分: 7

请尝试传递HTTP版本:

HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.build();
英文:

Please try passing HTTP version:

HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.build();

答案3

得分: 1

这个解决方案对我有效,

HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
英文:

This solution works for me,

HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();

答案4

得分: 0

在我的情况下,似乎是企业 VPN 导致了这个问题。你在使用企业 VPN 或代理吗?

另一个用户在这个问题上有类似的经历,链接在这里:https://intellij-support.jetbrains.com/hc/en-us/community/posts/4697679084434

英文:

In my case, it appeared to be the corporate VPN that caused this issue. Are you using a corporate VPN or proxy?

Another user shared a similar experience with this problem here.

huangapple
  • 本文由 发表于 2020年10月14日 20:48:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/64353620.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定