Android / Java:HttpURLConnection不会返回redirect文件的标题(例如在S3上)

我的代码(转载如下),连接到一个url,并将文件下载到Android上的磁盘。 所有标准的东西。 当我尝试在我们的服务器映射到一个存储区(例如foo.example.com => bucket,名为foo.example.com)上的子域访问S3上的文件上使用此代码时,它往往失败。 结果(使用方便的curl命令..

"curl -v -L -X GET http://foo.example.com/f/a.txt") 

..这里有一个redirect

文件下载工作正常,因为HttpURLConnection将默认遵循redirect,但需要标题信息(getContentLength,getHeaderFieldDate(“Last-Modified”,0)等)的调用返回来自307redirect的标题,而不是实际文件下载。

任何人都知道如何解决这个问题?

谢谢

 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); } 

Solutions Collecting From Web of "Android / Java:HttpURLConnection不会返回redirect文件的标题(例如在S3上)"

您是否尝试将redirect设置为false,并尝试使用它手动捕获redirect的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(); 

这个例子捕获redirect的URL,但你可以轻松地调整这个来尝试任何其他头字段。 这有帮助吗?

考虑使用httpclient-android 。 你应该在redirect后得到正确的头文件:

 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中执行此操作。

那么,我已经玩了一下,这个代码,它使用HttpClient库而不是HttpUrlConnection工作正常。 它返回的标题是最后一个redirect跃点的标题。 至less在我testing过的设备上。

 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(); } } }