java HttpURLConnection 得到 Redirect 转向的例子-DownloadService

DownloadThread.java (d:\android-5\packages\providers\downloadprovider\src\com\android\providers\downloads

 
/**
* Fully execute a single download request. Setup and send the request,
* handle the response, and transfer the data to the destination file.
*/
private void executeDownload() throws StopRequestException {
final boolean resuming = mInfoDelta.mCurrentBytes != 0;

URL url;
try {
// TODO: migrate URL sanity checking into client side of API
url = new URL(mInfoDelta.mUri);
} catch (MalformedURLException e) {
throw new StopRequestException(STATUS_BAD_REQUEST, e);
}

int redirectionCount = 0;
while (redirectionCount++ < Constants.MAX_REDIRECTS) {
// Open connection and follow any redirects until we have a useful
// response with body.
HttpURLConnection conn = null;
try {
checkConnectivity();
conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(false);
conn.setConnectTimeout(DEFAULT_TIMEOUT);
conn.setReadTimeout(DEFAULT_TIMEOUT);

addRequestHeaders(conn, resuming);

final int responseCode = conn.getResponseCode();
switch (responseCode) {
case HTTP_OK:
if (resuming) {
throw new StopRequestException(
STATUS_CANNOT_RESUME, “Expected partial, but received OK”);
}
parseOkHeaders(conn);
transferData(conn);
return;

case HTTP_PARTIAL:
if (!resuming) {
throw new StopRequestException(
STATUS_CANNOT_RESUME, “Expected OK, but received partial”);
}
transferData(conn);
return;

case HTTP_MOVED_PERM:
case HTTP_MOVED_TEMP:
case HTTP_SEE_OTHER:
case HTTP_TEMP_REDIRECT:
final String location = conn.getHeaderField(“Location”);
url = new URL(url, location);
if (responseCode == HTTP_MOVED_PERM) {
// Push updated URL back to database
mInfoDelta.mUri = url.toString();
}
continue;

case HTTP_PRECON_FAILED:
throw new StopRequestException(
STATUS_CANNOT_RESUME, “Precondition failed”);

case HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
throw new StopRequestException(
STATUS_CANNOT_RESUME, “Requested range not satisfiable”);

case HTTP_UNAVAILABLE:
parseUnavailableHeaders(conn);
throw new StopRequestException(
HTTP_UNAVAILABLE, conn.getResponseMessage());

case HTTP_INTERNAL_ERROR:
throw new StopRequestException(
HTTP_INTERNAL_ERROR, conn.getResponseMessage());

default:
StopRequestException.throwUnhandledHttpError(
responseCode, conn.getResponseMessage());
}

} catch (IOException e) {
if (e instanceof ProtocolException
&& e.getMessage().startsWith(“Unexpected status line”)) {
throw new StopRequestException(STATUS_UNHANDLED_HTTP_CODE, e);
} else {
// Trouble with low-level sockets
throw new StopRequestException(STATUS_HTTP_DATA_ERROR, e);
}

} finally {
if (conn != null) conn.disconnect();
}
}

throw new StopRequestException(STATUS_TOO_MANY_REDIRECTS, “Too many redirects”);
}

 

 

http://www.yihaomen.com/article/java/369.htm

 

做网站的人,都知道可以在apache,iis里配置 302,302转向,这样对搜索引擎也是有好的。如果用java开发程序得到这个链接的话,通常是得不到真实的转向地址的,这需要手工处理。

程序代码 程序代码
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setInstanceFollowRedirects(true);  //you still need to handle redirect manully.
HttpURLConnection.setFollowRedirects(true);

如果在服务端,从原始的url 转向另一个url 那么得到的response 应该是:
301:moved permanently
302:temporary redirect
其实,可以通过 HTTP response 的 头部 :”Location” 得到这个转向的url。比如有一个例子,从http://www.twitter.com 自动转向https 的站点:https://www.twitter.com

一个例子如下:

程序代码 程序代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpRedirectExample {

public static void main(String[] args) {

try {

String url = “http://www.twitter.com“;

URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.addRequestProperty(“Accept-Language”, “en-US,en;q=0.8”);
conn.addRequestProperty(“User-Agent”, “Mozilla”);
conn.addRequestProperty(“Referer”, “google.com”);

System.out.println(“Request URL … ” + url);

boolean redirect = false;

// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
redirect = true;
}

System.out.println(“Response Code … ” + status);

if (redirect) {

// get redirect url from “location” header field
String newUrl = conn.getHeaderField(“Location”);

// get the cookie if need, for login
String cookies = conn.getHeaderField(“Set-Cookie”);

// open the new connnection again
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn.setRequestProperty(“Cookie”, cookies);
conn.addRequestProperty(“Accept-Language”, “en-US,en;q=0.8”);
conn.addRequestProperty(“User-Agent”, “Mozilla”);
conn.addRequestProperty(“Referer”, “google.com”);

System.out.println(“Redirect to URL : ” + newUrl);

}

BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer html = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
html.append(inputLine);
}
in.close();

System.out.println(“URL Content… \n” + html.toString());
System.out.println(“Done”);

} catch (Exception e) {
e.printStackTrace();
}

}

}

输出的结果为:

程序代码 程序代码
Request URL … http://www.twitter.com
Response Code … 301
Redirect to URL : https://twitter.com/
URL Content…
<!DOCTYPE html><!–[if IE 8]><html class= // twitter.com url content…