处理HttpClient重定向

时间:2011-03-02 15:12:07

标签: java httpclient

我正在将一些数据发布到正在回复302 Moved Temporarily的服务器上。

我希望HttpClient遵循重定向并自动获取新位置,因为我认为这是HttpClient的默认行为。但是,我得到了一个例外而没有遵循重定向:(

以下是相关的代码,任何想法都将受到赞赏:

HttpParams httpParams = new BasicHttpParams();
HttpClientParams.setRedirecting(httpParams, true);
SchemeRegistry schemeRegistry = registerFactories();
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);

HttpClient httpClient = new DefaultHttpClient(clientConnectionManager, httpParams)
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HTTP.CONTENT_TYPE, contentType);
postRequest.setHeader(ACCEPT, contentType);

if (requestBodyString != null) {
    postRequest.setEntity(new StringEntity(requestBodyString));
}

return httpClient.execute(postRequest, responseHandler);

4 个答案:

答案 0 :(得分:73)

对于HttpClient 4.3

HttpClient instance = HttpClientBuilder.create()
                     .setRedirectStrategy(new LaxRedirectStrategy()).build();

对于HttpClient 4.2

DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());

对于HttpClient < 4.2

DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new DefaultRedirectStrategy() {
    /** Redirectable methods. */
    private String[] REDIRECT_METHODS = new String[] { 
        HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME 
    };

    @Override
    protected boolean isRedirectable(String method) {
        for (String m : REDIRECT_METHODS) {
            if (m.equalsIgnoreCase(method)) {
                return true;
            }
        }
        return false;
    }
});

答案 1 :(得分:34)

HttpClient的默认行为符合HTTP规范(RFC 2616)的要求

10.3.3 302 Found
...

   If the 302 status code is received in response to a request other
   than GET or HEAD, the user agent MUST NOT automatically redirect the
   request unless it can be confirmed by the user, since this might
   change the conditions under which the request was issued.

您可以通过对DefaultRedirectStrategy进行子类化并覆盖其#isRedirected()方法来覆盖HttpClient的默认行为。

答案 2 :(得分:1)

默认情况下,http重定向似乎处于禁用状态。我尝试启用,它工作,但我仍然有问题的错误。但我们仍然可以务实地处理重定向。我认为你的问题可以解决: 旧代码:

AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User-Agent");
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
long contentSize = httpResponse.getEntity().getContentLength();

如果http重定向发生,此代码将返回contentSize = -1

然后在尝试启用默认跟随重定向后,我自己处理重定向

AndroidHttpClient client;
HttpGet httpGet;
HttpResponse response;
HttpHeader httpHeader;
private void handleHTTPRedirect(String url) throws IOException {
    if (client != null)
        client.close();

    client = AndroidHttpClient.newInstance("User-Agent");
    httpGet = new HttpGet(Network.encodeUrl(url));
    response = client.execute(httpGet);
    httpHeader = response.getHeaders("Location");
    while (httpHeader.length > 0) {
        client.close();
        client = AndroidHttpClient.newInstance("User-Agent");

        httpGet = new HttpGet(Network.encodeUrl(httpHeader[0].getValue()));
        response = client.execute(httpGet);
        httpHeader = response.getHeaders("Location");
    }
}

使用中

handleHTTPRedirect(url);
long contentSize = httpResponse.getEntity().getContentLength();

由于 阮

答案 3 :(得分:0)

我的解决方案是使用HttClient。我不得不将响应发送给调用者。这是我的解决方案

    CloseableHttpClient httpClient = HttpClients.custom()
            .setRedirectStrategy(new LaxRedirectStrategy())
            .build();

    //this reads the input stream from POST
    ServletInputStream str = request.getInputStream();

    HttpPost httpPost = new HttpPost(path);
    HttpEntity postParams = new InputStreamEntity(str);
    httpPost.setEntity(postParams);

    HttpResponse httpResponse = null ;
    int responseCode = -1 ;
    StringBuffer response  = new StringBuffer();

    try {

        httpResponse = httpClient.execute(httpPost);

        responseCode = httpResponse.getStatusLine().getStatusCode();
        logger.info("POST Response Status::  {} for file {}  ", responseCode, request.getQueryString());

        //return httpResponse ;
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                httpResponse.getEntity().getContent()));

        String inputLine;
        while ((inputLine = reader.readLine()) != null) {
            response.append(inputLine);
        }
        reader.close();

        logger.info(" Final Complete Response {}  " + response.toString());
        httpClient.close();

    } catch (Exception e) {

        logger.error("Exception ", e);

    } finally {

        IOUtils.closeQuietly(httpClient);

    }

    // Return the response back to caller
    return  new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);