web-dev-qa-db-fra.com

Gestion des redirections HttpClient

Je publie certaines données sur un serveur qui répond à un 302 déplacé temporairement.

Je veux que HttpClient suive la redirection et obtienne automatiquement le nouvel emplacement, car je crois que c'est le comportement par défaut de HttpClient. Cependant, je reçois une exception et je ne suis pas la redirection :(

Voici le morceau de code pertinent, toutes les idées seront appréciées:

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);
34
mgv

Le comportement par défaut de HttpClient est conforme aux exigences de la spécification HTTP (RFC 2616)

 10.3.3 302 trouvés 
...

 Si le code d'état 302 est reçu en réponse à une demande, autre 
 que GET ou HEAD, l’agent utilisateur NE DOIT PAS automatiquement rediriger le fichier 
 demande à moins que cela ne puisse être confirmé par l'utilisateur, car cela pourrait 
 changer les conditions dans lesquelles la demande a été émise .

Vous pouvez remplacer le comportement par défaut de HttpClient en sous-classant DefaultRedirectStrategy et en remplaçant sa méthode #isRedirected (). 

33
oleg

Pour HttpClient 4.3

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

Pour HttpClient 4.2

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

Pour 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;
    }
});
71
RTF

Il semble que la redirection http est désactivée par défaut. J'essaie de l'activer, ça marche mais j'ai toujours une erreur avec mon problème. Mais nous pouvons toujours gérer la redirection de manière pragmatique. Je pense que votre problème peut résoudre: Si vieux code:

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

Ce code renverra contentSize = -1 si une redirection HTTP est survenue.

Et puis je gère la redirection par moi-même après avoir essayé d'activer la redirection suivante par défaut

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

Utilisé

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

Merci Nguyen

1
khaintt

Ma solution utilise HttpClient. Je devais renvoyer la réponse à l'appelant. C'est ma solution 

    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);
0
vsingh