在Java中检索给定URL的最终位置
我试图检索给定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();
如果有人看到上面的代码有任何问题,请欣赏评论。
UPDATE
- 删除了代码1xx的处理,因为大多数评论者认为没有必要。
-
在返回之前测试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();
如果协议更改,HttpURLConnection将不会遵循重定向,例如http到https或https到http。 在这种情况下,它将返回3xx代码,您应该能够获得Location标头。 如果新url也重定向,您可能需要再次打开连接。 所以基本上,当你得到一个非重定向响应代码时,使用一个循环并打破它。 另外,注意无限重定向循环,您可以设置迭代次数的限制或检查是否已经访问过每个新的URL。
可能很容易有多个级别的重定向 – 想象一下。指向youtu.be地址指向youtube.com。 也许你需要循环,直到你得到你的200 OK或直到你达到重定向周期。
我无法找到要检查的源代码,但我相信我说的是真的。 请参阅例如java urlconnection获取最终重定向的URL
您还可能需要处理协议重定向,例如HTTP – > HTTPS: URLConnection不遵循重定向
如果您只想要重定向url,则响应标头应该为您提供:
if (con.getResponseCode() == 301) { String redirectUrl = con.getHeaderField("Location"); }
我想我现在明白你想要什么。 我现在认为您正在尝试检索最终地址,而不是最终地址的内容。 如果我的假设错了,请纠正我。
要做到这一点(不是内容,而是地址),你需要一个不同的方法。 您需要关闭跟随重定向,然后您需要自己处理迭代重定向跟踪,直到找到非重定向响应。 请记住,您不能重复使用URLConnection
。
查找最终地址的方法和检索最终地址内容的另一种方法是如此不同,因为如果您打开后续重定向, URLConnection
不会显示后续地址。
在您的代码中,您似乎期望URLConnection.getURL()
返回跟随地址。 这不是此方法的行为。 它返回您用于创建URLConnection
的原始URL
。 无论你是否打开跟随重定向,它都会这样做。
但是,如果将其打开,则无法获取后续URL地址。 这是因为具有跟随重定向的getHeaderField("Location")
没有意义:它返回最终重定向的重定向目标,该重定向不应该存在,因为它是最终地址。
- Android:如何使用HttpsURLConnection以编程方式登录网页
- Java HttpURLConnection InputStream.close()挂起(或工作时间太长?)
- HttpURLConnection c = URL.openConnection(); c.setRequestProperty()不起作用
- 来自一个HttpURLConnection的几个请求
- 使用HttpClient模拟HTTP POST的问题
- URLConnection没有得到字符集
- 如果服务器返回错误状态,java.net.HttpUrlConnection是否总是抛出IOException?
- 是否可以使用HttpClient下载PDF等文件?
- 是否可以仅使用JDK或HttpComponents处理JSON响应?