2010-09-07 35 views
21

Je veux accéder à un site qui nécessite d'abord une authentification (serveur Tomcat), puis me connecter avec une requête POST et garder cet utilisateur pour voir les pages du site. J'utilise HttpClient 4.0.1Httpclient 4, erreur 302. Comment rediriger?

La première authentification fonctionne très bien, mais pas l'ouverture de session qui se plaint toujours de cette erreur: « 302 Déplacé temporairement »

Je garde les cookies & je garde un contexte et encore 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 est la redirection automatique.

Après mon code, qui jette toujours le 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 
     } 
    } 
+2

"La première authentification fonctionne très bien, mais pas l'ouverture de session qui se plaint toujours de cette erreur". Une redirection 302 n'est pas une plainte du serveur; c'est une indication que l'agent-utilisateur doit maintenant passer à la nouvelle page indiquée dans la réponse. –

+0

Je pensais ça, mais comment? J'essaie alors une demande GET mais en vain. – juanmirocks

Répondre

36

Pour 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; 
     } 
    }); 
+3

Je ne pense pas que cela devrait retourner false, je pense qu'il devrait retourner isRedirect. Quand j'ai fait ce changement, ce code a fonctionné. Merci! –

+3

Cela fonctionne, mais dans la plupart des cas, les demandes POST sont remplacées par des demandes GET par le serveur http. Et si la cible (par exemple une servlet) n'accepte que les requêtes POST, la redirection automatique échoue avec le code d'état 405 (méthode non autorisée). Aucune suggestion? –

+0

Hé j'ai essayé ceci, alors que cela fonctionne bien dans un projet java je l'ai essayé dans Android et je reçois quelque chose de quelque chose de similaire à ce qui est décrit ici http://stackoverflow.com/questions/9255150/android-app-not-recognizing -setredirectstrategy Que suggérez-vous? J'ai importé les bibliothèques httpclient 4.2 –

1
httpclient.setRedirectHandler(new DefaultRedirectHandler()); 

Voir HttpClient Javadoc

+1

Cela ne fonctionne pas. Une autre idée? – juanmirocks

5

Vous devez implémenter gestionnaire de redirection personnalisée qui indique que la réponse à POST est une redirection . Cela peut être fait en substituant 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 classe est DefaultRedirectStrategy, mais une solution similaire peut être utilisé là-bas.

+0

le retour devrait être isRedirect et non faux – Shaybc

+0

Merci. J'ai mis à jour la réponse. –

1

Redirects ne sont pas traitées automatiquement par HttpClient 4.1 pour d'autres méthodes que GET et PUT.

17

Dans les versions ultérieures de HttpClient (4.1+), vous pouvez tout faire:

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

LaxRedirectStrategy redirigera automatiquement HEAD, GET et POST demandes. Pour une implémentation plus stricte, utilisez DefaultRedirectStrategy.

+1

Cela n'a pas été introduit dans 4.1, il a été introduit dans 4.2. –

0
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. 
16

Pour HttpClient 4.3.x:

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