原因:java.io.IOException:HTTP/1.1标头解析器未收到字节

问题描述 投票:0回答:5

我是第一次

原因: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()); // dbg - it's ok

            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();
                }
            }

这是代码。为什么我会收到此错误?

java ioexception
5个回答
16
投票

HTTP 标头是服务器响应的“第一件事”。 该错误表明它是空的。实际上,这个错误,粗略地翻译,意味着:“服务器绝对没有发回任何信息并挂断”。

这也解释了为什么“它以前有效”。不是你;就是那个服务器。它已损坏、离线或已更新或替换,因此无法再处理您的请求。

这个+其他链接的SO答案建议你强制使用HTTP/1.1模式 - 你只是在调整发送请求的方式,希望你可以调整它,这样服务器就不会被它阻塞。很可能服务器刚刚离线,您所要做的就是等待一段时间或与管理员联系。还可以尝试使用例如连接到 URL curl 或您的浏览器来查看发生了什么。

另一个常见原因是他们只是将 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("Uncaught", e);
。当发生你懒得处理的事情时,你最不想做的就是“默默地什么也不做”。您希望崩溃具有适当的堆栈跟踪。
    
请尝试传递 HTTP 版本:


10
投票

这个解决方案对我有用,

2
投票

就我而言,似乎是
企业 VPN

0
投票

另一位用户在这里分享了类似的经历。

就我而言,问题是由过时的服务器引起的,该服务器不理解默认的 HttpClient 的“用户代理”参数:“Java-http-client/21.0.1”。


0
投票
“user-agent”

设置为

“Mozilla/5.0 (Linux)”

,如下面的代码片段所示: HttpClient client = HttpClient.newBuilder() .version(Version.HTTP_1_1) .followRedirects(Redirect.NORMAL) .connectTimeout(Duration.ofSeconds(20)) .build(); URI uri = new URI(url_); HttpRequest request = HttpRequest.newBuilder() .uri(uri) .header("user-agent", "Mozilla/5.0 (Linux; Android 6.0)") .GET() .build();

© www.soinside.com 2019 - 2024. All rights reserved.