Java通过带身份认证的URL下载文件触发重定向次数过多错误如何解决
问题修复方案
你遇到的java.net.ProtocolException: Server redirected too many times (20) 本质是请求循环重定向,核心原因是自动重定向过程中身份凭证或会话Cookie丢失,服务器始终判定请求未认证,不断触发登录跳转逻辑,形成死循环。
可按以下方案逐步修复:
- 方案1:禁用默认自动重定向,手动处理跳转逻辑,保证每次请求都携带认证信息
- 方案2:调整认证账号格式,如果你的企业内网用的是域账号认证(比如NTLM、AD认证),需要把用户名改为「域名\用户名」的格式,示例:
String username = "MYDOMAIN\\User123"; - 方案3:检查URL协议一致性,如果你填写的是HTTP地址,实际内网会强制跳转HTTPS,建议直接将URL的协议改为HTTPS,减少不必要的跳转。
以下是修改后可直接运行的代码示例,手动处理重定向逻辑,同时兼容Basic认证场景:
import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.Base64; public class JavaDownloadFileFromURL { // 认证信息 private static final String USERNAME = "User123"; private static final String PASSWORD = "pwd123"; // 最大重定向次数,避免死循环 private static final int MAX_REDIRECTS = 5; public static void main(String[] args) { String url = "http://ourintranet.site.com/some/path/file.docx"; try { downloadWithManualRedirect(url, "/Users/Me/Documents/test.docx"); System.out.println("文件下载成功"); } catch (IOException e) { e.printStackTrace(); } } private static void downloadWithManualRedirect(String urlStr, String savePath) throws IOException { String currentUrl = urlStr; int redirectCount = 0; while (redirectCount < MAX_REDIRECTS) { URL url = new URL(currentUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 禁用自动重定向 conn.setInstanceFollowRedirects(false); // 手动添加Basic认证头,非Basic认证场景可删除这三行代码,保留原有Authenticator配置即可 String auth = USERNAME + ":" + PASSWORD; String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes()); conn.setRequestProperty("Authorization", "Basic " + encodedAuth); int responseCode = conn.getResponseCode(); // 判断是否是重定向响应 if (responseCode >= 300 && responseCode < 400) { String newUrl = conn.getHeaderField("Location"); // 处理相对路径的重定向地址 if (newUrl.startsWith("/")) { newUrl = url.getProtocol() + "://" + url.getHost() + newUrl; } currentUrl = newUrl; redirectCount++; conn.disconnect(); } else if (responseCode == 200) { // 响应正常,开始下载文件 try (BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); FileOutputStream fos = new FileOutputStream(savePath)) { byte[] buffer = new byte[1024]; int count; while ((count = bis.read(buffer, 0, 1024)) != -1) { fos.write(buffer, 0, count); } } conn.disconnect(); return; } else { conn.disconnect(); throw new IOException("请求异常,响应码:" + responseCode); } } throw new IOException("重定向次数超过上限" + MAX_REDIRECTS + "次,最终跳转地址:" + currentUrl); } }
内容的提问来源于stack exchange,提问作者Shathos
相关产品推荐
相关产品推荐

