Android/Java:HttpURLConnection不';t返回重定向文件的标题(例如在S3上)
我的代码(复制如下)连接到一个url,并将文件下载到android上的磁盘上。所有标准的东西。当我尝试在S3上的一个文件上使用此代码时,该文件是通过服务器上映射到bucket(例如foo.example.com=>bucket,名为foo.example.com)的子域访问的,它经常失败。结果是(使用方便的curl命令Android/Java:HttpURLConnection不';t返回重定向文件的标题(例如在S3上),android,redirect,download,httpurlconnection,Android,Redirect,Download,Httpurlconnection,我的代码(复制如下)连接到一个url,并将文件下载到android上的磁盘上。所有标准的东西。当我尝试在S3上的一个文件上使用此代码时,该文件是通过服务器上映射到bucket(例如foo.example.com=>bucket,名为foo.example.com)的子域访问的,它经常失败。结果是(使用方便的curl命令 "curl -v -L -X GET http://foo.example.com/f/a.txt") …这里有一个重定向 文件下载工作正常,因为默认情况下HttpURLC
"curl -v -L -X GET http://foo.example.com/f/a.txt")
…这里有一个重定向
文件下载工作正常,因为默认情况下HttpURLConnection将遵循重定向,但需要标头信息(getContentLength、getHeaderFieldDate(“Last Modified”,0)等)的调用将返回307重定向中的标头,而不是下载的实际文件
有人知道怎么避开这个吗
谢谢
File local = null;
try {
Log.i(TAG, "Downloading file " + source);
conn = (HttpURLConnection) new URL(source).openConnection();
fileSize = conn.getContentLength(); // ** THIS IS WRONG ON REDIRECTED FILES
out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024);
conn.connect();
stream = new BufferedInputStream(conn.getInputStream(), 8 * 1024);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
while (true) {
int read = stream.read(buffer);
if (read == -1) {
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
publishProgress(downloaded, fileSize);
if (isCancelled()) {
return "The user cancelled the download";
}
}
} catch (Exception e) {
String msg = "Failed to download file " + source + ". " + e.getMessage();
Log.e(TAG, msg );
return msg;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
} else {
long dateLong = conn.getHeaderFieldDate("Last-Modified", 0 ); // ** THIS IS WRONG ON REDIRECTED FILES
Date d = new Date(dateLong);
local.setLastModified(dateLong);
}
您是否尝试将重定向设置为false,并尝试手动捕获重定向的URL及其关联的标题字段 例如,类似这样的事情:
URL url = new URL(url);
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setInstanceFollowRedirects(false);
URL secondURL = new URL(ucon.getHeaderField("Location"));
URLConnection conn = secondURL.openConnection();
此示例捕获重定向的URL,但您可以轻松地调整它以尝试任何其他标头字段。这是否有帮助?好吧,我已经播放了一段时间,这段代码使用HttpClient库而不是HttpUrlConnection运行良好。它返回的标头是最终重定向跃点的标头。 至少在我测试过的设备上
HttpClient client = null;
HttpGet get = null;
HttpResponse response = null;
try {
client = new DefaultHttpClient();
get = new HttpGet(source);
response = client.execute(get);
Header contentSize = response.getFirstHeader("Content-Length");
if (contentSize != null) {
String value = contentSize.getValue();
fileSize = Long.parseLong(value);
}
if (fileSize == -1) {
Log.e(TAG, "Failed to read the content length for the file " + source);
}
Header lastModified = response.getFirstHeader("Last-Modified");
lastModifiedDate = null;
if (lastModified != null) {
lastModifiedDate = DateUtils.parseDate(lastModified.getValue());
}
if (lastModifiedDate == null) {
Log.e(TAG, "Failed to read the last modified date for the file " + source);
}
out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024); // false means don't append
stream = new BufferedInputStream(response.getEntity().getContent(), 8 * 1024);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
int count = 0;
while (true) {
int read = stream.read(buffer);
if (read == -1) {
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
publishProgress(downloaded, fileSize);
if (isCancelled()) {
Log.w(TAG, "User Cancelled");
return; // NOTE that onPostExecute is not called here..
}
}// end of while
publishProgress(downloaded, fileSize);
} catch (Exception e) {
String msg = "Failed to download file " + source + ". " + e.getMessage();
Log.e(TAG, msg );
return msg;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
}
考虑使用。重定向后,您应该使用以下命令获得正确的头:
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(YOUR_URL);
HttpResponse response = client.execute(request);
response.getAllHeaders()
请注意,android附带了一个较旧版本的httpclient,但它与您报告的问题相同。您需要导入“httpclient android”以获得较新版本
注意:代码片段是针对v4.3的。对于其他版本,请查看如何在常规apache HttpClient中执行此操作。谢谢。我想它可能会对多个重定向有点麻烦,但这可能会很有帮助。我在各种Android组件的重定向代码中遇到了其他奇怪的问题。即使在同一操作系统版本上,不同的设备也会处理这些问题结果我们切换到了手动重定向。啊,很有趣。我一直在尝试使用apache HttpClient而不是HttpURLConnection,它对我很有效(到目前为止!).您对哪些android组件有问题?我使用的代码几乎完全相同,它在android 4.1 emulator中给出重定向的url,但在android 2.2.2设备中相同的代码返回“null”!您知道为什么会失败吗?