已解决java.net.HttpRetryException异常的正确解决方法,亲测有效!!!

发布时间:2024年01月21日

已解决java.net.HttpRetryException异常的正确解决方法,亲测有效!!!

文章目录

问题分析

报错原因

解决思路

解决方法

总结


在使用Java进行HTTP编程时,我们可能会遇到各种类型的异常。其中,java.net.HttpRetryException是一个特殊的IO异常,发生在HTTP请求需要重新发送但不能自动处理时。本文将根据问题分析、报错原因、解决思路和解决方法四个方面详细讨论这个问题。

?

问题分析

假设你正在编写一个Java程序,该程序用于向一个HTTP服务器发送POST请求。你首先创建了一个HttpURLConnection对象,然后设置请求方式为"POST",填充输出流并发送请求。代码可能如下:

import java.net.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.example.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);

            OutputStream os = conn.getOutputStream();
            // 填充输出流...
            
            conn.connect();
            // 处理响应...
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当你运行此代码时,如果服务器返回了一个需要重新请求(比如HTTP 307/308临时重定向)但HttpURLConnection无法自动处理的状态码,你收到以下错误消息:

??

java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1681) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1595) at Main.main(Main.java:15)

??

在这个例子中,错误发生的原因是HttpURLConnection对象试图自动处理HTTP重定向,但由于正在流模式(streaming mode)下发送数据,所以不能重新发送请求。

报错原因

根据Java官方文档,java.net.HttpRetryException异常在以下情况下抛出:

  • HTTP协议需要重新发送一个请求,但无法自动执行。这通常发生在接收到某些特定的HTTP响应码(如307 Temporary Redirect和308 Permanent Redirect)但当前处于流模式发送数据时。
  • HTTP服务器要求认证。当服务器返回401 Unauthorized或者407 Proxy Authentication Required响应,并且缺失有效的认证信息时,也会抛出此异常。

在我们的问题中,报错原因是处于流模式下的POST请求遇到了HTTP重定向。

?

解决思路

解决java.net.HttpRetryException异常的关键在于理解并解决其抛出条件。具体来说,有两种可能的策略:

  1. 避免处于流模式下的HTTP请求遇到重定向。你可以考虑关闭HttpURLConnection的自动重定向功能,并手动处理重定向。
  2. 提供正确的认证信息,以满足服务器的认证要求。

?

解决方法

基于上述解决思路,我们可以通过以下步骤解决问题:

  1. 关闭HttpURLConnection的自动重定向功能。添加conn.setInstanceFollowRedirects(false);语句。

  2. 手动处理HTTP重定向。在连接后,检查HTTP响应码并根据需要处理重定向。

  3. 如果服务器要求认证,提供有效的认证信息。

修改后的代码如下:

import java.net.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.example.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setInstanceFollowRedirects(false);  // 关闭自动重定向

            OutputStream os = conn.getOutputStream();
            // 填充输出流...
            
            conn.connect();
            int responseCode = conn.getResponseCode();
            // 处理响应...
            if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP
                    || responseCode == HttpURLConnection.HTTP_MOVED_PERM) {
                // 手动处理HTTP重定向
                String location = conn.getHeaderField("Location");
                url = new URL(location);
                conn = (HttpURLConnection) url.openConnection();
                // 重新发送请求...
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们首先关闭了HttpURLConnection的自动重定向功能。然后,在收到HTTP 307或308响应时,从"Location"头获取新的URL,并重新建立连接。

总结

总的来说,java.net.HttpRetryException异常发生在需要重新发送HTTP请求但无法自动处理时。解决这个问题的关键是理解你的HTTP请求何时以及如何引发此异常,并据此修改代码,例如关闭自动重定向、手动处理重定向、提供有效的认证信息等。

以上是此问题报错原因的解决方法,欢迎评论区留言讨论是否能解决,如果本文对你有帮助 欢迎 关注?、点赞?、收藏?、评论,?博主才有动力持续记录遇到的问题!!!

博主v:XiaoMing_Java

?📫作者简介:嗨,大家好,我是?小明java问道之路互联网大厂后端研发专家,2022博客之星TOP3 / 博客专家 / CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网5万粉丝博主。


🍅 文末获取联系 🍅??👇🏻 精彩专栏推荐订阅收藏 👇🏻

专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

🔥Redis从入门到精通与实战🔥

Redis从入门到精通与实战

围绕原理源码讲解Redis面试知识点与实战

🔥MySQL从入门到精通🔥

MySQL从入门到精通

全面讲解MySQL知识与企业级MySQL实战

🔥计算机底层原理🔥

深入理解计算机系统CSAPP

以深入理解计算机系统为基石,构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

🔥数据结构与企业题库精讲🔥

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

🔥互联网架构分析与实战🔥

企业系统架构分析实践与落地

行业最前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

互联网金融公司的防资损方法论、代码与实践

🔥Java全栈白宝书🔥

精通Java8与函数式编程

本专栏以实战为基础,逐步深入Java8以及未来的编程模式

深入理解JVM

详细介绍内存区域、字节码、方法底层,类加载和GC等知识

深入理解高并发编程

深入Liunx内核、汇编、C++全方位理解并发编程

Spring源码分析

Spring核心七IOC/AOP等源码分析

MyBatis源码分析

MyBatis核心源码分析

Java核心技术

只讲Java核心技术

文章来源:https://blog.csdn.net/FMC_WBL/article/details/135736927
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。