2011-07-14 18 views
15

का उपयोग कर परिपत्र रीडायरेक्ट से बचें HttpClient 4.1.1 का उपयोग करके परिपत्र पुनर्निर्देशन से कैसे बच सकता हूं। मैं इस तरह त्रुटि हो रही है के रूप में: -HttpClient 4.1.1

executing requestGET http://home.somehost.com/Mynet/pages/cHome.xhtml HTTP/1.1 
org.apache.http.client.ClientProtocolException 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at edu.uci.ics.crawler4j.url.WebURL.setURL(WebURL.java:122) 
    at edu.uci.ics.crawler4j.crawler.CrawlController.addSeed(CrawlController.java:207) 
    at edu.uci.ics.crawler4j.example.advanced.Controller.main(Controller.java:31) 
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to 'http://home.somehost.com/Mynet/pages/Home.xhtml' 
    at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:168) 
    at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:193) 
    at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1021) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:482) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 

यह मेरा कोड ...

DefaultHttpClient client = null; 

     try 
     { 
      // Set url 
      //URI uri = new URI(url.toString()); 

      client = new DefaultHttpClient(); 

      client.getCredentialsProvider().setCredentials(
        new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), 
        new UsernamePasswordCredentials("test", "test")); 


      URL url1 = new URL (url); 
      HttpURLConnection connection = (HttpURLConnection) url1.openConnection(); 
      connection.setFollowRedirects(false); 

      HttpGet request = new HttpGet(url); 
      final HttpParams params = new BasicHttpParams(); 
      HttpClientParams.setRedirecting(params, false); 
      HttpContext context = new BasicHttpContext(); 

      System.out.println("----------------------------------------"); 
      System.out.println("executing request" + request.getRequestLine()); 
      HttpResponse response = client.execute(request, context); 
      HttpEntity entity = response.getEntity(); 


      System.out.println(response.getStatusLine()); 
        InputStream content = entity.getContent(); 
        BufferedReader in = 
         new BufferedReader (new InputStreamReader (content)); 
        String line; 
        while ((line = in.readLine()) != null) { 
         // System.out.println(line); 
        } 
       } catch(Exception e) { 
        e.printStackTrace(); 
       } 
+0

क्या आप वाकई यह बच सकते हैं? यदि वास्तव में एक गोलाकार पुनर्निर्देशन है, तो अपवाद फेंकना यह इंगित करने के लिए एक उचित तरीका है। – nos

+0

@nos पीछे जवाब देने के लिए धन्यवाद .. मुझे परिपत्र पुनर्निर्देशन के लिए एक ही यूआरएल वापस मिल रहा है। लेकिन अगर मैं ब्राउज़र पर उस यूआरएल टाइप करता हूं तो मुझे उसी यूआरएल के साथ सर्वर से तीन प्रतिक्रिया मिलती है। पहले 302 मंद गति है। दूसरा 302 पाया गया है, तीसरा 200 ठीक है .. उसी यूआरएल के साथ ... और मैं इस यूआरएल की सामग्री को पकड़ना चाहता हूं। – ferhan

उत्तर

31

आप क्लाइंटप्रेम.ALLOW_CIRCULAR_REDIRECTS को सत्य पर सेट कर सकते हैं, यह रीडायरेक्ट को उसी स्थान पर रीडायरेक्ट करने की अनुमति देगा।

client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); 

अधिक जानकारी here

+0

लिंक टूटा हुआ अनुरोधों से हेडर को मिलाकर मिलान करने के लिए आप 'टेलनेट' जैसे कुछ का उपयोग कर सकते हैं। – Youngjae

+8

यह वर्तमान संस्करण के लिए बहिष्कृत है। RequestConfig.custom() का उपयोग करें। SetCircularRedirectsAllowed (true) .build() इसके बजाए। – keiki

+0

वास्तव में एचटीपी क्लाइंट को रीडायरेक्ट त्रुटि फेंकने से रोकने के लिए यह नहीं है। इसका मतलब है कि रीडायरेक्ट अभी भी हो रहा है? जैसा कि एडम ने उल्लेख किया है, क्या इसे सर्वर पर स्थायी फिक्स की आवश्यकता नहीं है? –

2

तुम बस इसे टाला है। HttpClient परिपत्र पुनर्निर्देशन का पता चला और एक अपवाद फेंक दिया। अगर इसे "टाला" नहीं दिया गया था, तो यह हमेशा के लिए रीडायरेक्ट करना जारी रखेगा (जब तक आप प्रक्रिया को मारने का फैसला नहीं करते)। यदि अन्य सर्वर के साथ जवाब मिलता है तो बहुत सारे विकल्प नहीं हैं।

सर्कुलर रीडायरेक्ट लूप से वास्तव में बचने का एकमात्र तरीका सर्वर को ठीक करना है।

यदि आप सोच रहे हैं कि क्या हो रहा है (जैसे ब्राउज़र में यह काम क्यों लगता है लेकिन आपके प्रोग्राम से नहीं), तो कुछ अतिरिक्त HttpClient लॉगिंग को चालू करने का प्रयास करें। विशेष रूप से, सुनिश्चित करें कि आप सभी HTTP शीर्षलेखों को आगे और पीछे भेज सकते हैं। जब आप अपने ब्राउज़र में एक ही अनुरोध करते हैं, तो मतभेदों को ध्यान में रखते हुए आप वार्तालाप को देख सकते हैं। यह एक लापता कुकी, पागल ब्राउज़र का पता लगाने, आदि हो सकता है ...

आपके ब्राउज़र के संचार का पता लगाने के कई तरीके हैं।

  • फ़ायरफ़ॉक्स + HttpFox (या LiveHttpHeaders, Firebug, आदि ...)
  • Fiddler (केवल Windows)
  • : यहां ऐसे कुछ तरीके (IMHO) है कि मैं अक्सर मुश्किल के लिए सबसे आसान से क्रम में उपयोग करते हैं, कर रहे हैं
  • Wireshark/tcpdump

निम्न स्तर के परीक्षण के लिए, टेलनेट का उपयोग कर (जब तक आप विंडोज, जिस स्थिति में आप PuTTY/plink की तरह कुछ के साथ बंद बेहतर हो सकता है का उपयोग करें) और क्या परिवर्तन परिपत्र रीडायरेक्ट का कारण/बाहर में सत्तारूढ़ प्रयास करें।

+0

पीछे जवाब देने के लिए धन्यवाद .. मुझे परिपत्र पुनर्निर्देशन के लिए एक ही यूआरएल वापस मिल रहा है। लेकिन अगर मैं ब्राउज़र पर उस यूआरएल टाइप करता हूं तो मुझे उसी यूआरएल के साथ सर्वर से तीन प्रतिक्रिया मिलती है। पहले 302 मंद गति है। दूसरा 302 पाया गया है, तीसरा 200 ठीक है .. उसी यूआरएल के साथ ... और मैं इस यूआरएल की सामग्री को पकड़ना चाहता हूं। – ferhan

+0

मैंने समस्या का निदान करने के लिए कुछ सुझावों के साथ अपना उत्तर अपडेट किया है –

+0

मैं अपने फ़ायरफ़ॉक्स में फायरबग का उपयोग कर रहा हूं .. इसलिए जब मैं प्रतिक्रिया वापस देखता हूं तो फायरबग में .. मुझे लगता है कि 302 मिले, 302 अस्थायी रूप से स्थानांतरित हो गए, फिर 200 ओके के लिए मेरे फायरबग में एक ही यूआरएल। – ferhan

2

वहाँ एक बग है कि 4.0 से अपाचे HttpClient में परिपत्र रीडायरेक्ट का कारण होगा है, तो यह और भी नवीनतम संस्करण में तय नहीं किया गया था देखें।

DefaultRequestDirector.java में, यह बनाता है एक HttpRedirect पुनर्निर्देशन प्रदर्शन करने के लिए, और यह अपने मूल HttpGet में सभी हेडर का पुन: उपयोग होगा, समस्या यहाँ यह भी पुन: उपयोग होगा होस्ट हैडर, जिसका अर्थ सर्वर अभी भी मूल मिल जाएगा है नए यूआरआई पर रीडायरेक्ट करने के प्रयास के बाद होस्ट करें।

मैं DefaultRequestDirector reimplemented द्वारा इस तय:

public class RedirectRequestDirector extends DefaultRequestDirector 
{ 
    RedirectRequestDirector(
      final HttpRequestExecutor requestExec, 
      final ClientConnectionManager conman, 
      final ConnectionReuseStrategy reustrat, 
      final ConnectionKeepAliveStrategy kastrat, 
      final HttpRoutePlanner rouplan, 
      final HttpProcessor httpProcessor, 
      final HttpRequestRetryHandler retryHandler, 
      final RedirectHandler redirectHandler, 
      final AuthenticationHandler targetAuthHandler, 
      final AuthenticationHandler proxyAuthHandler, 
      final UserTokenHandler userTokenHandler, 
      final HttpParams params) 
    { 
     super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params); 

    } 
    @Override 
    protected RoutedRequest handleResponse(RoutedRequest roureq, 
      HttpResponse response, 
      HttpContext context) 
        throws HttpException, IOException 
    { 
     RoutedRequest req = super.handleResponse(roureq, response, context); 
     if(req != null) 
     { 
      String redirectTarget = req.getRoute().getTargetHost().getHostName(); 
      req.getRequest().getOriginal().setHeader("Host", redirectTarget); 
     } 
     return req; 
    } 

} 

और DefaultHttpClient:

public class RedirectHttpClient extends DefaultHttpClient 
{ 
    @Override 
    protected RequestDirector createClientRequestDirector(
      final HttpRequestExecutor requestExec, 
      final ClientConnectionManager conman, 
      final ConnectionReuseStrategy reustrat, 
      final ConnectionKeepAliveStrategy kastrat, 
      final HttpRoutePlanner rouplan, 
      final HttpProcessor httpProcessor, 
      final HttpRequestRetryHandler retryHandler, 
      final RedirectHandler redirectHandler, 
      final AuthenticationHandler targetAuthHandler, 
      final AuthenticationHandler proxyAuthHandler, 
      final UserTokenHandler stateHandler, 
      final HttpParams params) { 
     return new RedirectRequestDirector(
       requestExec, 
       conman, 
       reustrat, 
       kastrat, 
       rouplan, 
       httpProcessor, 
       retryHandler, 
       redirectHandler, 
       targetAuthHandler, 
       proxyAuthHandler, 
       stateHandler, 
       params); 
    } 
} 

अब मैं परिपत्र पुनर्निर्देशन के बारे में शिकायत नहीं होंगे।

0

जांचें कि आपके अनुरोध को आपके द्वारा अनुरोधित यूआरएल पर भेजने से पहले प्रॉक्सी को भेजा नहीं गया है।

0

आप कोशिश कर सकते हैं:

RequestConfig requestConfig = RequestConfig.custom() 
           .setCircularRedirectsAllowed(true) 
           .build(); 

HttpClient httpClient = HttpClients.custom() 
         .setDefaultRequestConfig(requestConfig) 
         .setRedirectStrategy(new LaxRedirectStrategy()) 
         .build(); 

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); 
requestFactory.setHttpClient(httpClient); 
संबंधित मुद्दे