为何HttpURLConnection的GET方法在部分站点返回404错误?
问题原因及修复方案
核心问题1:GET请求错误设置setDoOutput(true)
HttpURLConnection中调用setDoOutput(true)时,会默认把请求方法从GET改为POST。而lemmy.world这类站点的路由严格区分请求方法,POST请求访问根路径会直接返回404,这就是你遇到问题的关键——Python的requests.get和curl默认都是标准GET请求,所以能正常访问。
核心问题2:未读取服务器响应内容
你的代码里StringBuilder sb完全没有被使用,既没读取输入流的内容,也没检查响应状态码,导致返回的结果一直是空字符串,也没法及时发现请求的实际错误。
修复后的完整代码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; public class HttpUtils { public static String get(String urlString, Map<String, String> headers) { HttpURLConnection urlConnection = null; StringBuilder sb = new StringBuilder(); String responseString = null; URL url = null; try { url = new URL(urlString); System.out.println(url); } catch (IOException e) { e.printStackTrace(); return null; } try { if (url != null) { urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setReadTimeout(10000); urlConnection.setConnectTimeout(10000); urlConnection.setInstanceFollowRedirects(true); // 移除setDoOutput(true),GET请求无需向服务器输出内容 urlConnection.setDoInput(true); urlConnection.setRequestProperty("Accept", "*/*"); urlConnection.setRequestProperty("Connection", "Keep-Alive"); urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); if (headers != null && !headers.isEmpty()) { for (Map.Entry<String, String> entry : headers.entrySet()) { urlConnection.setRequestProperty(entry.getKey(), entry.getValue()); } } // 检查响应状态码,方便调试 int responseCode = urlConnection.getResponseCode(); System.out.println("Response Code: " + responseCode); // 根据响应码选择对应输入流(处理成功/错误响应) BufferedReader reader; if (responseCode >= 200 && responseCode < 300) { reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); } else { reader = new BufferedReader(new InputStreamReader(urlConnection.getErrorStream())); } String line; while ((line = reader.readLine()) != null) { sb.append(line); } reader.close(); responseString = sb.toString(); if (DeviceUtils.isEmulator()) { System.out.println("Response: " + responseString); } } } catch (IOException e) { e.printStackTrace(); } finally { if (urlConnection != null) { urlConnection.disconnect(); } } return responseString; } }
额外说明
- 移除
setDoOutput(true):确保请求保持GET方法,适配目标站点的路由规则。 - 新增响应状态码检查:直观查看请求结果,便于调试问题。
- 补充响应内容读取逻辑:无论成功还是错误响应,都读取对应流,避免返回空结果。
- 增加finally块关闭连接:防止资源泄漏。
内容的提问来源于stack exchange,提问作者Cris
相关产品推荐
相关产品推荐

