প্রাপ্যতার জন্য HTTP URL টি পিং করার জন্য পছন্দের জাভা উপায়


157

আমার একটি মনিটরের শ্রেণি দরকার যা নিয়মিত কোনও HTTP URL পাওয়া যায় কিনা তা পরীক্ষা করে দেখে। আমি স্প্রিং টাস্কএক্সেকিউটার বিমূর্ততা ব্যবহার করে "নিয়মিত" অংশটির যত্ন নিতে পারি, তাই এখানে বিষয়টি এখানে নয়। প্রশ্নটি হল: জাভাতে ইউআরএল পিন করার পছন্দের উপায়টি কী?

শুরুর পয়েন্ট হিসাবে এখানে আমার বর্তমান কোডটি রয়েছে:

try {
    final URLConnection connection = new URL(url).openConnection();
    connection.connect();
    LOG.info("Service " + url + " available, yeah!");
    available = true;
} catch (final MalformedURLException e) {
    throw new IllegalStateException("Bad URL: " + url, e);
} catch (final IOException e) {
    LOG.info("Service " + url + " unavailable, oh no!", e);
    available = false;
}
  1. এটি কি আদৌ কোনও ভাল (আমি যা চাই তা কি তা করবে)?
  2. আমার কি কোনওভাবে সংযোগটি বন্ধ করতে হবে?
  3. আমি মনে করি এটি একটি GETঅনুরোধ। HEADপরিবর্তে পাঠানোর কোনও উপায় আছে ?

উত্তর:


267

এটি কি আদৌ কোনও ভাল (আমি যা চাই তা কি তা করবে?)

আপনি এটি করতে পারেন। আর একটি সম্ভাব্য উপায় ব্যবহার করা হচ্ছে java.net.Socket

public static boolean pingHost(String host, int port, int timeout) {
    try (Socket socket = new Socket()) {
        socket.connect(new InetSocketAddress(host, port), timeout);
        return true;
    } catch (IOException e) {
        return false; // Either timeout or unreachable or failed DNS lookup.
    }
}

এছাড়াও আছে InetAddress#isReachable():

boolean reachable = InetAddress.getByName(hostname).isReachable();

তবে এটি সুস্পষ্টভাবে পোর্ট ৮০ পরীক্ষা করে না Fire


আমার কি কোনওভাবে সংযোগটি বন্ধ করতে হবে?

না, আপনার স্পষ্টভাবে দরকার নেই। এটি হুডগুলির নীচে পরিচালনা এবং পুল করা হয়।


আমি মনে করি এটি জিইটি অনুরোধ is পরিবর্তে কি হেড পাঠানোর কোনও উপায় আছে?

আপনি প্রাপ্ত কাস্ট করতে পারেন URLConnectionথেকে HttpURLConnectionএবং তারপর ব্যবহার setRequestMethod()অনুরোধ পদ্ধতি সেট করতে। যাইহোক, আপনার অ্যাকাউন্টে নেওয়া দরকার যে কিছু জিইটি পুরোপুরি সূক্ষ্মভাবে কাজ করার সময় কিছু দুর্বল ওয়েব অ্যাপস বা হোমগ্রাউন সার্ভারগুলি একটি হেডের জন্য HTTP 405 ত্রুটি ফিরিয়ে দিতে পারে (যেমন উপলব্ধ নয়, কার্যকর নয়, অনুমোদিত নয়)। আপনি ডোমেন / হোস্ট নয় লিঙ্কগুলি / সংস্থানগুলি যাচাই করতে চান এমন ক্ষেত্রে জিইটি ব্যবহার করা আরও নির্ভরযোগ্য।


প্রাপ্যতার জন্য সার্ভারটি পরীক্ষা করা আমার ক্ষেত্রে পর্যাপ্ত নয়, আমার ইউআরএল পরীক্ষা করতে হবে (ওয়েবপ্যাপটি স্থাপন করা হতে পারে না)

প্রকৃতপক্ষে, হোস্টের সংযোগ কেবল হোস্টটি উপলব্ধ থাকলে তা জানায়, সামগ্রীটি উপলভ্য নয়। এটি যতটা ভাল ঘটতে পারে যে কোনও সমস্যা ছাড়াই একটি ওয়েবসার্ভার শুরু হয়েছে, তবে সার্ভারের শুরুর সময় ওয়েব অ্যাপটি মোতায়েন করতে ব্যর্থ হয়েছিল। এটি সাধারণত পুরো সার্ভারটি নীচে নামার কারণ হবে না। আপনি HTTP প্রতিক্রিয়া কোডটি 200 কিনা তা পরীক্ষা করে নির্ধারণ করতে পারেন।

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
    // Not OK.
}

// < 100 is undetermined.
// 1nn is informal (shouldn't happen on a GET/HEAD)
// 2nn is success
// 3nn is redirect
// 4nn is client error
// 5nn is server error

প্রতিক্রিয়া স্থিতি কোড সম্পর্কে আরও তথ্যের জন্য দেখুন আরএফসি 2616 বিভাগ 10connect()আপনি প্রতিক্রিয়া ডেটা নির্ধারণ করলে কলিংয়ের প্রয়োজন হয় না। এটি সুস্পষ্টভাবে সংযুক্ত হবে।

ভবিষ্যতের রেফারেন্সের জন্য, টাইমআউটগুলির সাথে অ্যাকাউন্ট গ্রহণ করে কোনও ইউটিলিটি পদ্ধতির স্বাদে এখানে একটি সম্পূর্ণ উদাহরণ:

/**
 * Pings a HTTP URL. This effectively sends a HEAD request and returns <code>true</code> if the response code is in 
 * the 200-399 range.
 * @param url The HTTP URL to be pinged.
 * @param timeout The timeout in millis for both the connection timeout and the response read timeout. Note that
 * the total timeout is effectively two times the given timeout.
 * @return <code>true</code> if the given HTTP URL has returned response code 200-399 on a HEAD request within the
 * given timeout, otherwise <code>false</code>.
 */
public static boolean pingURL(String url, int timeout) {
    url = url.replaceFirst("^https", "http"); // Otherwise an exception may be thrown on invalid SSL certificates.

    try {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setConnectTimeout(timeout);
        connection.setReadTimeout(timeout);
        connection.setRequestMethod("HEAD");
        int responseCode = connection.getResponseCode();
        return (200 <= responseCode && responseCode <= 399);
    } catch (IOException exception) {
        return false;
    }
}

3
বিশদগুলির জন্য ধন্যবাদ, এর মতো উত্তরগুলি এসওকে একটি দুর্দান্ত জায়গা করে তোলে। প্রাপ্যতার জন্য সার্ভারটি পরীক্ষা করা আমার ক্ষেত্রে পর্যাপ্ত নয়, আমার ইউআরএল পরীক্ষা করতে হবে (ওয়েবপ্যাপটি স্থাপন করা হতে পারে না), তাই আমি এইচটিটিপিআরএল সংযোগের সাথে লেগে থাকব। হেড সম্পর্কে একটি ভাল পরীক্ষা হচ্ছে না: এটি যদি আমি জানতে পারি টার্গেট ইউআরএল হেডকে সমর্থন করে তবে এটি একটি ভাল পদ্ধতি I'll
শান প্যাট্রিক ফ্লয়েড

1
জাভা.আইও.আইওএক্সেপশন পাওয়া সম্ভব : কিছু সার্ভারে স্ট্রিমের অপ্রত্যাশিত সমাপ্তি , এটি ঠিক করার জন্য আপনাকে সংযোগ.সেটরেক্সেস্টপ্রোপার্টি যুক্ত করতে হবে ("স্বীকৃতি-এনকোডিং", "মিউজিকমেচ"); এটি সমস্যা হিসাবে পরিচিত এবং কোড. google.com
মার্সিন ওয়াননিস্কি

1
@ বালুসসি কারণ (200 <= রেসপন্স কোড && প্রতিক্রিয়া কোড <= 399) সত্য হবে যদি এবং কেবল যদি (প্রতিক্রিয়া <= 399) হয়, যার অর্থ (200 <= রেসপন্স কোড) শর্তটি অতিরিক্ত কাজ নয়। সুতরাং আমি ভেবেছিলাম এটি একটি ভুল ছিল।
মেটােটর

4
@ মিটার: হু ??? এটি একেবারে অপ্রয়োজনীয় নয়। 200 এর চেয়ে কম রেসপন্স কোডগুলি বৈধ বলে বিবেচিত হবে না।
বালুসসি

1
@ বালুসসি ইম কিছু পরিস্থিতি এই পদ্ধতিগুলি দেখে মনে হচ্ছে এটি ভালভাবে কাজ করে না। একবার দেখে এখানে দিতে stackoverflow.com/questions/25805580/...
AndreaF

17

পরিবর্তে URLConnection ব্যবহার ব্যবহারের HttpURLConnection আপনার URL বস্তুর উপর openConnection () কল করে।

তারপরে getResponseCode ব্যবহার করুন () আপনি সংযোগটি একবার পড়ার পরে আপনাকে HTTP প্রতিক্রিয়া দেবে।

এখানে কোড:

    HttpURLConnection connection = null;
    try {
        URL u = new URL("http://www.google.com/");
        connection = (HttpURLConnection) u.openConnection();
        connection.setRequestMethod("HEAD");
        int code = connection.getResponseCode();
        System.out.println("" + code);
        // You can determine on HTTP return code received. 200 is success.
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }

এছাড়াও অনুরূপ প্রশ্নটি পরীক্ষা করে দেখুন কীভাবে কোনও URL টি উপস্থিত রয়েছে বা জাভা দিয়ে 404 ফেরত আসে কিনা তা পরীক্ষা করে দেখুন?

আশাকরি এটা সাহায্য করবে.


7

আপনি এইচটিটিপিআরএল সংযোগও ব্যবহার করতে পারেন যা আপনাকে অনুরোধের পদ্ধতিটি সেট করতে দেয় (উদাহরণস্বরূপ শিরোনামে )। এখানে একটি উদাহরণ যা দেখায় যে কীভাবে একটি অনুরোধ পাঠানো যায়, প্রতিক্রিয়াটি পড়তে হবে এবং সংযোগ বিচ্ছিন্ন করতে হয়।


4

নিম্নলিখিত কোড HEADওয়েবসাইট উপলব্ধ কিনা তা যাচাই করার জন্য একটি অনুরোধ সম্পাদন করে ।

public static boolean isReachable(String targetUrl) throws IOException
{
    HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(
            targetUrl).openConnection();
    httpUrlConnection.setRequestMethod("HEAD");

    try
    {
        int responseCode = httpUrlConnection.getResponseCode();

        return responseCode == HttpURLConnection.HTTP_OK;
    } catch (UnknownHostException noInternetConnection)
    {
        return false;
    }
}

4

এখানে লেখক এটি পরামর্শ দিয়েছেন:

public boolean isOnline() {
    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    } catch (IOException | InterruptedException e) { e.printStackTrace(); }
    return false;
}

সম্ভাব্য প্রশ্ন

  • এটি কি আসলেই যথেষ্ট দ্রুত? হ্যাঁ, খুব দ্রুত!
  • আমি কি আমার নিজস্ব পৃষ্ঠাটি পিং করতে পারি না, যা আমি যাইহোক অনুরোধ করতে চাই? নিশ্চিত! এমনকি আপনি উভয়ই পরীক্ষা করে দেখতে পারেন, যদি আপনি "ইন্টারনেট সংযোগ উপলব্ধ" এবং আপনার নিজস্ব সার্ভারের মধ্যে পৌঁছনীয় e গুগল ডিএনএস (উদাঃ ৮.৮.৮.৮) বিশ্বের বৃহত্তম পাবলিক ডিএনএস পরিষেবা। 2013 হিসাবে এটি একদিনে 130 বিলিয়ন অনুরোধ পরিবেশন করে। কেবলমাত্র এটিই বলা যাক, আপনার অ্যাপ্লিকেশন সাড়া না দেওয়া সম্ভবত সেদিনের আলোচনার বিষয় নয়।

লিঙ্কটি পড়ুন। এটা খুব ভাল বলে মনে হচ্ছে

সম্পাদনা: এটি ব্যবহারের পরে আমার এক্সপ্রেসে এটি এই পদ্ধতির মতো দ্রুত নয়:

public boolean isOnline() {
    NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

এগুলি কিছুটা আলাদা তবে কেবলমাত্র ইন্টারনেটের সাথে সংযোগ পরীক্ষা করার জন্য কার্যক্ষমতায় প্রথম পদ্ধতিটি সংযোগের ভেরিয়েবলের কারণে ধীর হয়ে যেতে পারে।


2

রেস্টলেট ফ্রেমওয়ার্কটি ব্যবহার করার বিষয়টি বিবেচনা করুন, যার মধ্যে এই ধরণের জিনিসটির জন্য দুর্দান্ত শব্দার্থবিদ্যা রয়েছে। এটি শক্তিশালী এবং নমনীয়।

কোডটি এতটা সহজ হতে পারে:

Client client = new Client(Protocol.HTTP);
Response response = client.get(url);
if (response.getStatus().isError()) {
    // uh oh!
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.