2010-09-07 21 views
21

Bir (tomcat sunucu) kimlik doğrulaması gerektiren ve daha sonra bir POST isteğiyle oturum açıp sitenin sayfalarını görmesini sağlayan bir siteye erişmek istiyorum. Kullandığım HttpClient 4.0.1Httpclient 4, 302 hatası. Nasıl yönlendirilir?

ilk kimlik doğrulama çalışıyor ama her zaman bu hata hakkında şikayet değil oturum açma:

Kurabiye & Bir bağlam ve henüz hiçbir şey tutmak tutmak "302 geçici taşındı". Aslında, oturum açma işlevi göründüğü için yanlış parametre veya kullanıcı şifresi yazarsam giriş sayfasını görüyorum. Bu yüzden işe yaramazsa otomatik yönlendirme olduğunu düşünüyorum. hep IOException atar kodumu, ardından

, 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

"İlk kimlik doğrulama çalışıyor ama her zaman bu hata hakkında şikayet değil oturum açma". 302 yönlendirme, sunucu tarafından bir şikayet değildir; Bu, kullanıcı aracısının artık yanıtta belirtilen yeni sayfaya gitmesi gerektiğinin bir göstergesidir. –

+0

Bunu düşündüm ama nasıl? O zaman bir GET isteği deneyin ama boşuna. – juanmirocks

cevap

36

:

Yönlendirme GET ve PUT dışındaki yöntemler için HttpClient 4.1 tarafından otomatik işlenmez
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

Bunun yanlış geri dönmesi gerektiğini düşünmüyorum, sanırım bu isRedirect'e dönmelidir. Bu değişikliği yaptığımda, bu kod işe yaradı. Teşekkürler! –

+3

Çalışıyor, ancak çoğu durumda POST istekleri http sunucusu tarafından GET isteklerine dönüştürülür. Ve eğer hedef (örneğin bir sunucu için) sadece POST taleplerini kabul ederse, otomatik yönlendirme 405 durum koduyla başarısız olur (Yönteme izin verilmez). Baska öneri? –

+0

Hey Bunu denedim, bu bir java projesinde iyi çalışırken Android'de denedim ve http://stackoverflow.com/questions/9255150/android-app-not-recognizing adresinde anlatılana benzer bir şey elde ediyorum. -setredirectstrategy Ne önerirsiniz? Httpclient 4.2 kitaplıklarını aldım. –

1
httpclient.setRedirectHandler(new DefaultRedirectHandler()); 

Javadoc Sen POST o tepkiyi gösterecektir özel yönlendirme işleyicisi uygulamak zorunda

+1

Bu işe yaramıyor. Başka bir fikrin var mı? – juanmirocks

5

bir anlam ayrımı HttpClient bakın . Bu, aşağıda gösterildiği gibi isRedirectRequested() yöntemini geçersiz kılarak yapılabilir. HttpClient sonraki sürümünde

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

, sınıf adı DefaultRedirectStrategy olmakla benzer çözüm var kullanılabilir. 4.1 sürümü için

+0

döndürme isRedirect olmalı ve yanlış değil – Shaybc

+0

Teşekkürler. Cevabı güncelledim. –

1

. HttpClient sonraki sürümlerinde

17

(4.1+), sadece bunu yapabilirsiniz:

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

LaxRedirectStrategy otomatik HEAD yönlendirme GET ve POST istekleri olacaktır. Daha sıkı bir uygulama için DefaultRedirectStrategy kullanın. HttpClient 4.3.x için

+1

Bu, 4.1'de tanıtılmadı, 4.2'de tanıtıldı. –

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

:

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