我正在尝试检索给定URL的最终位置(String ref),如下所示:
HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
con.setInstanceFollowRedirects(true);
con.setRequestProperty("User-Agent","");
int responseCode = con.getResponseCode();
return con.getURL().toString();
它适用于大多数情况,但很少返回包含另一个重定向的URL。
我在这里做错了什么?
为什么即使在调用setInstanceFollowRedirects(true)之后我也得到responseCode = 3xx?
更新
好的,responseCode有时可以是3xx。
如果它发生,那么我将返回con.getHeaderField(“Location”)。
现在的代码是:
HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
con.setInstanceFollowRedirects(true);
con.setRequestProperty("User-Agent","");
int responseType = con.getResponseCode()/100;
while (responseType == 1)
{
Thread.sleep(10);
responseType = con.getResponseCode()/100;
}
if (responseType == 3)
return con.getHeaderField("Location");
return con.getURL().toString();
如果有人发现上述代码有任何问题,请欣赏评论。
更新
在返回之前测试Location标头是否存在,以便处理代码304。
HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
con.setInstanceFollowRedirects(true);
con.setRequestProperty("User-Agent","");
if (con.getResponseCode()/100 == 3)
{
String target = con.getHeaderField("Location");
if (target != null)
return target;
}
return con.getURL().toString();
答案 0 :(得分:3)
如果协议发生更改,HttpURLConnection将不会遵循重定向,例如http到https或https到http。在这种情况下,它将返回3xx代码,您应该能够获得Location标头。如果新网址也重定向,您可能需要再次打开连接。所以基本上,当你得到一个非重定向响应代码时,使用一个循环并打破它。另外,请注意无限重定向循环,您可以设置迭代次数的限制或检查是否已经访问过每个新的URL。
答案 1 :(得分:1)
可能很容易有多个级别的重定向 - 想象一下。指向指向youtube.com的youtu.be地址。也许你需要循环,直到你得到你的200 OK或直到你达到重定向周期。
我无法找到要检查的源代码,但我相信我说的是真的。参见例如java urlconnection get the final redirected URL
您还可能需要处理协议重定向,例如HTTP - > HTTPS:URLConnection Doesn't Follow Redirect
答案 2 :(得分:0)
如果您只想要重定向网址,则响应标头应该为您提供:
if (con.getResponseCode() == 301) {
String redirectUrl = con.getHeaderField("Location");
}
答案 3 :(得分:0)
我想我现在明白你想要什么。我现在认为您正在尝试检索最终地址,而不是最终地址的内容。如果我的假设是错误的,请纠正我。
为了做到这一点(不是内容,而是地址),你需要一个不同的方法。您需要关闭跟随重定向,然后您需要自己处理迭代重定向跟踪,直到找到非重定向响应。请记住,您无法重复使用URLConnection
。
查找最终地址的方法和检索最终地址内容的其他方法是如此不同,因为如果您切换,URLConnection
不会显示后续地址关于跟随重定向。
在您的代码中,您似乎希望URLConnection.getURL()
返回后续地址。这不是此方法的行为。它会返回您用于创建URL
的原始URLConnection
。无论你是否打开跟随重定向,它都会这样做
但是,如果将其打开,则无法获取后续URL地址。这是因为具有跟随重定向的getHeaderField("Location")
没有意义:它返回最终重定向的重定向目标,该重定向不应该存在,因为它是最终地址。
答案 4 :(得分:0)
有时它正在请求URL的字段中加载。像这样的代码使用:
val declaredField = con.javaClass.getDeclaredField("requestURI")
declaredField.isAccessible=true
val loc = declaredField.get(con).toString()