Κοινή χρήση τεχνολογίας

Πώς η Java χρησιμοποιεί το HttpClientUtils για την εκκίνηση αιτημάτων HTTP

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


εισαγωγή

Στη σύγχρονη ανάπτυξη λογισμικού, είναι συχνά απαραίτητη η επικοινωνία με απομακρυσμένους διακομιστές, όπως η λήψη δεδομένων ή η αποστολή δεδομένων. Το Apache HttpClient είναι μια δημοφιλής βιβλιοθήκη προγράμματος-πελάτη Java HTTP που απλοποιεί την εκκίνηση και την επεξεργασία απόκρισης των αιτημάτων HTTP.Αυτό το άρθρο θα εισαγάγει τον τρόπο χρήσης μιας προσαρμογήςHttpClientUtils Κλάση για χρήση του Apache HttpClient για την εκκίνηση αιτημάτων POST και τη διαχείριση του χώρου συγκέντρωσης σύνδεσης για βελτιστοποίηση της απόδοσης.

Επισκόπηση κλάσης 1.HttpClientUtils

public class HttpClientUtils {
    // 静态常量和变量声明
    private static final int MAX_TOTAL_CONN = 600;
    private static final int MAX_CONN_PER_HOST = 300;
    private static final int SOCKET_TIMEOUT = 5000;
    private static final int CONNECTION_TIMEOUT = 200;
    private static final int CONNECTION_MANAGER_TIMEOUT = 100;

    private static CloseableHttpClient httpclient;
    private static PoolingHttpClientConnectionManager connMrg;
    private static String encoding = StandardCharsets.UTF_8.name();
    private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
    private static final ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(2);

    // 静态代码块,用于初始化 HttpClient 和连接管理器,并设置 JVM 退出时关闭 HttpClient
    static {
        init();
        destroyByJvmExit();
    }

    // 初始化连接管理器和 HttpClient
    private static void init() {
        connMrg = new PoolingHttpClientConnectionManager();
        connMrg.setMaxTotal(MAX_TOTAL_CONN);
        connMrg.setDefaultMaxPerRoute(MAX_CONN_PER_HOST);

        httpclient = HttpClients.custom()
                .setConnectionManager(connMrg)
                .setDefaultRequestConfig(HttpClientUtils.defaultRequestConfig())
                .build();

        // 定时任务,定期清理过期和空闲连接
        scheduledService.scheduleAtFixedRate(() -> {
            connMrg.closeExpiredConnections();
            connMrg.closeIdleConnections(CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);
        }, 0, CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);
    }

    // JVM 退出时关闭 HttpClient
    private static void destroyByJvmExit() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                httpclient.close();
            } catch (IOException e) {
                log.error("Error closing HttpClient: {}", e.getMessage());
            }
        }));
    }

    // 创建 HttpClientContext
    private static HttpClientContext createContext() {
        return HttpClientContext.create();
    }

    // 创建默认的 RequestConfig
    private static RequestConfig defaultRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(CONNECTION_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setConnectionRequestTimeout(CONNECTION_MANAGER_TIMEOUT)
                .build();
    }

    // 发起带参数的 POST 表单请求,返回字符串结果
    public static String postWithParamsForString(String url, List<NameValuePair> params) {
        HttpPost httpPost = new HttpPost();
        try {
            URI uri = new URIBuilder(url).build();
            httpPost.setURI(uri);
            httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));

            return executeRequest(httpPost);
        } catch (URISyntaxException | IOException e) {
            log.error("Error executing POST request: {}", e.getMessage());
        } finally {
            httpPost.releaseConnection();
        }
        return null;
    }
    
    // 发起 GET 请求,返回字符串结果
    public static String get(String url, List<NameValuePair> params) {
        HttpGet httpGet = new HttpGet();
        try {
            URI uri = new URIBuilder(url).setParameters(params).build();
            httpGet.setURI(uri);

            return executeRequest(httpGet);
        } catch (URISyntaxException | IOException e) {
            log.error("HTTP GET request failed", e);
        } finally {
            httpGet.releaseConnection();
        }
        return null;
    }

    // 发起 Post 请求,返回字符串结果
    public static String post(String url, List<NameValuePair> params) {
        HttpPost httpPost = new HttpPost();
        try {
            httpPost.setURI(new URI(url));
            httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));

            return executeRequest(httpPost);
        } catch (URISyntaxException | IOException e) {
            log.error("HTTP POST request failed", e);
        } finally {
            httpPost.releaseConnection();
        }
        return null;
    }

    // 执行 HTTP 请求并处理响应
    private static String executeRequest(HttpUriRequest request) throws IOException {
        try (CloseableHttpResponse response = httpclient.execute(request, createContext())) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, encoding);
                } else {
                    log.warn("Empty response entity");
                }
            } else {
                log.error("HTTP request failed with status code: {}", statusCode);
            }
        } catch (IOException e) {
            log.error("HTTP request execution failed: {}", e.getMessage());
            throw e;
        }
        return null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133

2. Αναλύστε την κλάση HttpClientUtils

  1. στατικές σταθερές και μεταβλητές:

    • Ορίζει σταθερές και μεταβλητές όπως ο μέγιστος αριθμός συνδέσεων, το χρονικό όριο σύνδεσης, το χρονικό όριο υποδοχής κ.λπ.
  2. Αρχικοποίηση και καταστροφή:

    • Αρχικοποιήθηκε σε μπλοκ στατικού κώδικα HttpClient και διαχειριστής σύνδεσηςPoolingHttpClientConnectionManager
    • χρήση ScheduledExecutorService Καθαρίζετε τακτικά τις ληγμένες και τις αδρανείς συνδέσεις.
    • υπάρχει destroyByJvmExit Στη μέθοδο, ένα άγκιστρο εξόδου JVM καταχωρείται για να διασφαλιστεί ότι είναι κλειστό όταν το JVM τερματίζεται.HttpClient
  3. Μέθοδος αιτήματος HTTP:

    • postWithParamsForString Η μέθοδος χρησιμοποιείται για την εκτέλεση ενός αιτήματος POST με παραμέτρους.
    • χρήση HttpPost Δημιουργήστε το αίτημα, ορίστε τη διεύθυνση URL και τις παραμέτρους αιτήματος και, τέλος, καλέστεexecuteRequest Αίτημα εκτέλεσης μεθόδου.
  4. Εκτελέστε αιτήματα και επεξεργαστείτε απαντήσεις:

    • executeRequest Μέθοδος λήψηςHttpUriRequest, εκτελέστε αιτήματα HTTP και επεξεργαστείτε απαντήσεις.
    • Ελέγξτε τον κωδικό κατάστασης της απάντησης και εάν είναι 200 ​​(ΟΚ), διαβάστε την οντότητα απάντησης και μετατρέψτε την σε συμβολοσειρά και επιστρέψτε την.
    • Χρησιμοποιήστε την καταγραφή για να καταγράψετε σφάλματα και προειδοποιητικά μηνύματα για να διασφαλίσετε την ευρωστία και την αξιοπιστία του κώδικά σας.

3. Χρησιμοποιήστε την κλάση HttpClientUtils

χρήση HttpClientUtils Οι τάξεις μπορούν να απλοποιήσουν τη σύνταξη και τη διαχείριση των αιτημάτων HTTP Τα συγκεκριμένα βήματα είναι τα εξής:

public class Main {
    public static void main(String[] args) {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("param1", "value1"));
        params.add(new BasicNameValuePair("param2", "value2"));

        String response = HttpClientUtils.postWithParamsForString("http://example.com/api", params);
        if (response != null) {
            System.out.println("Response: " + response);
        } else {
            System.err.println("Failed to execute POST request");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Μέσα από την παραπάνω εκμάθηση, θα πρέπει τώρα να καταλάβετε πώς να χρησιμοποιήσετε HttpClientUtils Κλάση για διαχείριση πελατών HTTP και εκκίνηση αιτημάτων. Αυτή η προσέγγιση μπορεί να σας βοηθήσει να χειριστείτε την επικοινωνία HTTP πιο αποτελεσματικά σε εφαρμογές Java, βελτιώνοντας παράλληλα την απόδοση και τη σταθερότητα μέσω της συγκέντρωσης συνδέσεων και των μηχανισμών περιοδικής εκκαθάρισης.