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开发程序得到这个链接的话,通常是得不到真实的转向地址的,这需要手工处理。

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.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();
}
}
}
输出的结果为:

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