HttpURLConnection मध्यांतर सेटिंग्स


123

मैं गलत लौटना चाहता हूं यदि URL को कनेक्ट होने में 5 सेकंड का समय लगता है - तो जावा का उपयोग कैसे संभव है? यहां वह कोड है जिसका उपयोग मैं यह जांचने के लिए कर रहा हूं कि क्या URL वैध है

HttpURLConnection.setFollowRedirects(false);
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);

जवाबों:


201

HttpURLConnectionएक सेटकनेक्ट टाइमआउट विधि है।

बस 5000 मिलीसेकंड तक टाइमआउट सेट करें, और फिर पकड़ें java.net.SocketTimeoutException

आपका कोड कुछ इस तरह दिखना चाहिए:


try {
   HttpURLConnection.setFollowRedirects(false);
   HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
   con.setRequestMethod("HEAD");

   con.setConnectTimeout(5000); //set timeout to 5 seconds

   return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
   return false;
} catch (java.io.IOException e) {
   return false;
}



3
मैंने मान 10 मिनट पर सेट किया। हालाँकि यह मुझे फेंकता है java.net.ConnectException: Connection timed out: connectइससे पहले कि 2 मिनट भी ऊपर हो। क्या आप जानते हैं कि समस्या क्या है?
पचेरियर

5
SocketTimeoutException IOException का एक उपवर्ग है। यदि दोनों कैच ब्लॉक समान कार्य करते हैं, तो आप केवल IOException को पकड़ सकते हैं।
स्पाकार्की 21

2
@ Spaaarky21 सही है। यदि आप यूआई का निर्माण कर रहे हैं और आप अपने उपयोगकर्ताओं को सूचित करना चाहते हैं कि एक टाइमआउट हुआ है, तो आपको IOException से पहले सॉकेट टाइमआउट अपवाद को पकड़ना होगा, यदि नहीं, तो यह पहुंच से बाहर होगा।
17

3
एनबी !!! आपको setConnectTimeoutउन तरीकों में से किसी से पहले कॉल करने की आवश्यकता है जो अंतर्निहित रूप से जुड़ते हैं (मूल रूप से सभी तरीके जो अवैध तरीके से पहले से ही जुड़े हैं, तो फेंक दें)। आदर्श तरीके से सेटकनेक्ट टाइमआउट (रीडटाइमआउट) करें जिसे पहले तरीके कहा जाता है।
एडम जेंट

4
यह मेरे लिए काम नहीं किया। लेकिन, जोड़ने के बाद con.setReadTimeout(), यह उम्मीद के मुताबिक काम किया।
पौलो

115

आप इस तरह टाइमआउट सेट कर सकते हैं,

con.setConnectTimeout(connectTimeout);
con.setReadTimeout(socketTimeout);

2
हमारे द्वारा निर्दिष्ट टाइमआउट का अधिकतम मूल्य क्या है?
पचेरियर

7
@ स्पेसर डॉक्स यह स्पष्ट रूप से नहीं बताता है। यह एक IllegalArgumentException को फेंक देता है यदि मान नकारात्मक है (0 का मान अनिश्चित काल तक प्रतीक्षा करेगा)। चूंकि टाइमआउट एक अहस्ताक्षरित 32 बिट इंट है, मुझे लगता है कि अधिकतम टाइमआउट लगभग 49 दिनों का होगा (हालांकि मुझे गंभीरता से संदेह है कि इस तरह का मूल्य किसी के लिए भी उपयोगी होगा)।
जे सिदरी

1

यदि HTTP कनेक्शन टाइमआउट नहीं होता है, तो आप टाइमआउट चेकर को बैकग्राउंड थ्रेड (AsyncTask, Service, etc) में लागू कर सकते हैं, निम्न वर्ग AsyncTask को कस्टमाइज़ करने के लिए एक उदाहरण है जो निश्चित अवधि के बाद टाइमआउट करता है।

public abstract class AsyncTaskWithTimer<Params, Progress, Result> extends
    AsyncTask<Params, Progress, Result> {

private static final int HTTP_REQUEST_TIMEOUT = 30000;

@Override
protected Result doInBackground(Params... params) {
    createTimeoutListener();
    return doInBackgroundImpl(params);
}

private void createTimeoutListener() {
    Thread timeout = new Thread() {
        public void run() {
            Looper.prepare();

            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {

                    if (AsyncTaskWithTimer.this != null
                            && AsyncTaskWithTimer.this.getStatus() != Status.FINISHED)
                        AsyncTaskWithTimer.this.cancel(true);
                    handler.removeCallbacks(this);
                    Looper.myLooper().quit();
                }
            }, HTTP_REQUEST_TIMEOUT);

            Looper.loop();
        }
    };
    timeout.start();
}

abstract protected Result doInBackgroundImpl(Params... params);
}

इसके लिए एक नमूना

public class AsyncTaskWithTimerSample extends AsyncTaskWithTimer<Void, Void, Void> {

    @Override
    protected void onCancelled(Void void) {
        Log.d(TAG, "Async Task onCancelled With Result");
        super.onCancelled(result);
    }

    @Override
    protected void onCancelled() {
        Log.d(TAG, "Async Task onCancelled");
        super.onCancelled();
    }

    @Override
    protected Void doInBackgroundImpl(Void... params) {
        // Do background work
        return null;
    };
 }

रद्द करने के लिए कॉल को शेड्यूल करने के लिए नया लूपर थ्रेड बनाना बिल्कुल अनावश्यक है। आप मुख्य धागे से कर सकते हैं onPreExecute()। साथ ही, यदि आप मैन्युअल रूप से कार्य को रद्द करते हैं, तो आपको लीक से बचने के लिए निर्धारित कॉल को भी रद्द करना चाहिए।
ब्लेडकोडर

यहाँ बिंदु DoInBackground के बीच में AsyncTask को रद्द करना है () जब निष्पादन में बहुत अधिक समय लगता है onPreExecute () में नहीं, तो भी मैं केवल AsyncTask के इस उदाहरण को रद्द करना चाहता हूं जिसमें बहुत अधिक समय लगता है और दूसरों को रखना चाहिए, बहुत सराहना आपकी प्रतिक्रिया।
अयमान महगूबे

2
मुझे लगता है कि मेरा संदेश पर्याप्त स्पष्ट नहीं था। मैंने नहीं कहा कि आपको onPreExecute () में रद्द करना चाहिए, मैंने कहा कि आपको onPreExecute () में हैंडलर बनाना चाहिए और मुख्य धागे से विलंबित रद्द करना चाहिए। इस तरह से आप मुख्य धागे का उपयोग लूपर धागे के रूप में करेंगे और आप बेशक बाद में AsyncTask को रद्द कर सकते हैं जबकि doInBackground () निष्पादित कर रहा है क्योंकि मुख्य धागा भी पृष्ठभूमि थ्रेड के साथ समवर्ती रूप से चलता है।
ब्लेडक्रोडर

-1

मैं एक साधारण रेखा के अतिरिक्त के साथ इस तरह की समस्या का समाधान प्राप्त कर सकता था

HttpURLConnection hConn = (HttpURLConnection) url.openConnection();
hConn.setRequestMethod("HEAD");

मेरी आवश्यकता प्रतिक्रिया कोड जानने की थी और उसके लिए केवल मेटा-जानकारी प्राप्त करना पर्याप्त था, बजाय पूर्ण प्रतिक्रिया निकाय के।

डिफ़ॉल्ट अनुरोध विधि GET है और जिसे वापस लौटने में बहुत समय लग रहा था, अंत में मुझे SocketTimeoutException को फेंकना पड़ा। जब मैं HEAD के लिए रिक्वेस्ट मेथड सेट करता था तो प्रतिक्रिया बहुत तेज थी।


1
यह किसी भी तरह से समाधान नहीं है, आप अनुरोध विधि को एक HEADअनुरोध में बदल रहे हैं जो किसी भी प्रतिक्रिया निकाय का उत्पादन नहीं करेगा।
स्विनुंग कावल बकेन

यह मूल प्रश्न से कुछ भी नहीं जोड़ता है। ओपी .setRequestMethod("HEAD")उनके कोड में है। अजीब तरह से, यह वर्णन वास्तव में मुझे अपने "बहुत सारी खुली फाइलों" के मुद्दे को कम करने की आवश्यकता थी। तो धन्यवाद?
जोशुआ पिंटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.