上周六我有时间调查你的问题。基本问题是,如果您需要获取Location
值,您需要停止自动重定向。以下是您的问题的解释和解决方案:
引用下载文件的 Box API 文档:
如果该文件可供下载,则响应将是 302 Found 到 dl.boxcloud.com 的 URL。
来自关于HTTP 302的维基百科文章:
HTTP 响应状态码 302 Found 是执行 URL 重定向的常用方法。
带有此状态代码的 HTTP 响应将在 Location 标头字段中另外提供一个 URL。带有此代码的响应邀请用户代理(例如 Web 浏览器)向 Location 字段中指定的新 URL 发出第二个(否则相同)请求。
因此,要获取Location
响应标头中的属性,您需要停止自动重定向。否则,根据 box doc,您将获得文件的原始数据,而不是下载 URL。
以下是使用Commons HTTPClient实现的解决方案:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String url = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
GetMethod getMethod = new GetMethod(url);
getMethod.setFollowRedirects(false);
Header header = new Header();
header.setName("Authorization");
header.setValue("Bearer " + accessToken);
getMethod.addRequestHeader(header);
HttpClient client = new HttpClient();
client.executeMethod(getMethod);
System.out.println("Status Code: " + getMethod.getStatusCode());
System.out.println("Location: " + getMethod.getResponseHeader("Location"));
} catch (Exception cause) {
cause.printStackTrace();
}
}
使用的替代解决方案java.net.HttpURLConnection
:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String serviceURL = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
URL url = new URL(serviceURL);
HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection());
connection.setRequestProperty("Authorization", "Bearer " + accessToken);
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(false);
connection.connect();
int statusCode = connection.getResponseCode();
System.out.println("Status Code: " + statusCode);
Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> locations = headerFields.get("Location");
if(locations != null && locations.size() > 0) {
System.out.println("Location: " + locations.get(0));
}
} catch (Exception cause) {
cause.printStackTrace();
}
}
由于 Commons HTTPClient 已过时,以下解决方案基于Apache HttpComponents:
private static void getFileDownloadUrl(String fileId, String accessToken) {
try {
String url = MessageFormat.format("https://api.box.com/2.0/files/{0}/content", fileId);
CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();
HttpGet httpGet = new HttpGet(url);
BasicHeader header = new BasicHeader("Authorization", "Bearer " + accessToken);
httpGet.setHeader(header);
CloseableHttpResponse response = client.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("Status Code: " + statusCode);
org.apache.http.Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
if(header != null && headers.length > 0) {
System.out.println("Location: " + headers[0]);
}
} catch (Exception cause) {
cause.printStackTrace();
}
}