3

我的代码如下

WebResource webResource1 = cl.resource("https://api.box.com/2.0/files/{fileId}/content");

ClientResponse res1 = webResource1.header("Authorization", "Bearer"+p1.getAccess_token()).get(ClientResponse.class);
String jsonStr1 = res1.getEntity(String.class);

我的回应如下 -

{Object-Id=[file_20317568941], Cache-control=[private], Date=[Wed, 24 Sep 2014 12:11:43 GMT], Content-Length=[27], X-Robots-Tag=[noindex, nofollow], Content-Disposition=[attachment;filename="upload.txt";filename*=UTF-8''upload.txt], Accept-Ranges=[bytes, bytes], Connection=[keep-alive], Content-Type=[text/plain; charset=UTF-8], Server=[nginx], X-Content-Type-Options=[nosniff]}

我收到状态码200, OK;但要获得location属性,我需要状态码302以及位置 url ( https://dl.boxcloud.com/*)。

如果没有在响应中获取location: https://dl.boxcloud.com/*属性,我如何从 box api 下载文件?

4

1 回答 1

2

上周六我有时间调查你的问题。基本问题是,如果您需要获取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();
    }
}
于 2014-10-20T08:28:52.633 回答