web-dev-qa-db-fra.com

Httpclient 4, erreur 302. Comment rediriger?

Je souhaite accéder à un site qui requiert une authentification (serveur Tomcat), puis me connecter avec une demande POST et laisser cet utilisateur consulter les pages du site. J'utilise Httpclient 4.0.1

La première authentification fonctionne bien, mais pas la connexion qui se plaint toujours de cette erreur: "302 déplacés temporairement"

Je garde les cookies et je garde un contexte et pourtant rien. En fait, il semble que la connexion fonctionne, car si j'écris des paramètres incorrects ou un mot de passe utilisateur ||, je vois la page de connexion. Donc, je suppose que ce qui ne fonctionne pas, c'est la redirection automatique. 

Après mon code, qui lève toujours l'IOException, 302:

    DefaultHttpClient httpclient = new DefaultHttpClient();
    CookieStore cookieStore = new BasicCookieStore();
    httpclient.getParams().setParameter(
      ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY); 
    HttpContext context = new BasicHttpContext();
    context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    //ResponseHandler<String> responseHandler = new BasicResponseHandler();

    Credentials testsystemCreds = new UsernamePasswordCredentials(TESTSYSTEM_USER,  TESTSYSTEM_PASS);
    httpclient.getCredentialsProvider().setCredentials(
            new AuthScope(AuthScope.ANY_Host, AuthScope.ANY_PORT),
            testsystemCreds);

    HttpPost postRequest = new HttpPost(cms + "/login");
    List<NameValuePair> formparams = new ArrayList<NameValuePair>();
    formparams.add(new BasicNameValuePair("pUserId", user));
    formparams.add(new BasicNameValuePair("pPassword", pass));
    postRequest.setEntity(new UrlEncodedFormEntity(formparams, "UTF-8"));
    HttpResponse response = httpclient.execute(postRequest, context);
    System.out.println(response);

    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
        throw new IOException(response.getStatusLine().toString());

    HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute( 
            ExecutionContext.HTTP_REQUEST);
    HttpHost currentHost = (HttpHost)  context.getAttribute( 
            ExecutionContext.HTTP_TARGET_Host);
    String currentUrl = currentHost.toURI() + currentReq.getURI();        
    System.out.println(currentUrl);

    HttpEntity entity = response.getEntity();
    if (entity != null) {
        long len = entity.getContentLength();
        if (len != -1 && len < 2048) {
            System.out.println(EntityUtils.toString(entity));
        } else {
            // Stream content out
        }
    }
22
juanmirocks

Pour la version 4.1:

DefaultHttpClient  httpclient = new DefaultHttpClient();
    httpclient.setRedirectStrategy(new DefaultRedirectStrategy() {                
        public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)  {
            boolean isRedirect=false;
            try {
                isRedirect = super.isRedirected(request, response, context);
            } catch (ProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (!isRedirect) {
                int responseCode = response.getStatusLine().getStatusCode();
                if (responseCode == 301 || responseCode == 302) {
                    return true;
                }
            }
            return isRedirect;
        }
    });
37
fvisticot

Dans les versions ultérieures de HttpCLient (4.1+), vous pouvez simplement faire ceci:

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

LaxRedirectStrategy redirigera automatiquement les requêtes HEAD, GET et POST. Pour une implémentation plus stricte, utilisez DefaultRedirectStrategy.

18
paradoxbomb

Pour HttpClient 4.3.x:

HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
18
Alix Lourme

Vous devez implémenter un gestionnaire de redirection personnalisé qui indiquera que la réponse à POST est une redirection. Cela peut être fait en surchargeant la méthode isRedirectRequested () comme indiqué ci-dessous.

DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectHandler(new DefaultRedirectHandler() {                
    @Override
    public boolean isRedirectRequested(HttpResponse response, HttpContext context) {
        boolean isRedirect = super.isRedirectRequested(response, context);
        if (!isRedirect) {
            int responseCode = response.getStatusLine().getStatusCode();
            if (responseCode == 301 || responseCode == 302) {
                return true;
            }
        }
        return isRedirect;
    }
});

Dans la version ultérieure de HttpClient, le nom de la classe est DefaultRedirectStrategy, mais une solution similaire peut être utilisée à cet endroit.

5
Shashikant Kore

HttpClient 4.1 ne gère pas automatiquement les redirections pour les méthodes autres que GET et PUT. 

1
Alin
httpclient.setRedirectHandler(new DefaultRedirectHandler());

Voir HttpClient Javadoc

1
Vivien Barousse
Extend the DefaultRedirectStrategy class and override the methods.
@Override
    protected URI createLocationURI(String arg0) throws ProtocolException {
        // TODO Auto-generated method stub
        return super.createLocationURI(arg0);
    }

    @Override
    protected boolean isRedirectable(String arg0) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public URI getLocationURI(HttpRequest arg0, HttpResponse arg1,
            HttpContext arg2) throws ProtocolException {
        // TODO Auto-generated method stub
        return super.getLocationURI(arg0, arg1, arg2);
    }

    @Override
    public HttpUriRequest getRedirect(HttpRequest request,
            HttpResponse response, HttpContext context)
            throws ProtocolException {
          URI uri = getLocationURI(request, response, context);
          String method = request.getRequestLine().getMethod();
          if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
              return new HttpHead(uri);
          } else {
              return new HttpPost(uri);
          }

    }

    @Override
    public boolean isRedirected(HttpRequest request, HttpResponse response,
            HttpContext context) throws ProtocolException {
        // TODO Auto-generated method stub
        return super.isRedirected(request, response, context);
    }

in this case isRedirectable method will always return true and getRedirect method will return post request in place of get request.
0
nat