Bagaimana saya bisa yakin bahwa HttpClient PostMethod berisi string UTF-8 di parameternya?

Di aplikasi web kami, kami harus mengirim permintaan POST melalui HttpClient ke titik akhir di jaringan kami, yang akan menerima ini dan melakukan beberapa pekerjaan dengannya. Kami mengalami masalah dengan pengkodean karakter, dan saya kesulitan menemukan jawaban atas pertanyaan saya.

Kami telah menggunakan metode postMethod.getParams().setContentCharset("UTF-8") saat mengirim permintaan, tetapi di pihak penerima, sepertinya karakter tersebut masih dikodekan dalam ISO 8859-1. Saya telah menentukan ini karena ketika saya memeriksa String di sisi penerima, ada karakter sampah di dalamnya yang hilang setelah saya mengikuti langkah-langkah yang ditemukan di https://stackoverflow.com/a/16549329/1130549. Apakah ada langkah tambahan yang perlu saya ambil di pihak pengiriman untuk memastikan bahwa saya benar-benar menulis karakter dalam UTF-8 seperti yang diharapkan? Yang kita lakukan sekarang adalah menggunakan postMethod.addParameter(paramKey, paramValue) dengan objek String asli.

Sunting: Berikut adalah contoh yang sangat sederhana tentang bagaimana kami mengirimkan permintaan POST. Nilainya diambil dari objek XMLBeans.

PostMethod postMethod = new PostMethod(url);
postMethod.getParams().setContentCharset("UTF-8");
postMethod.addParameter("key1", "value1");
postMethod.addParameter("key2", "value2");

HttpClient httpClient = new HttpClient();
int status = httpClient.executeMethod(postMethod);

person Mirrana    schedule 18.11.2019    source sumber


Jawaban (2)


EDIT Solusi yang lebih sederhana adalah dengan menyandikan nilainya

postMethod.addParameter("key1", URLEncoder.encode("value1","UTF-8"));

Untuk mengkodekan UTF-8 dengan benar, Anda dapat mengeksekusi secara berbeda, menggunakan StringEntity dan NameValuePair, misalnya:

try (CloseableHttpClient httpClient = HttpClients.custom().build()) {
   URIBuilder uriBuilder = new URIBuilder(url);
   HttpHost target = new HttpHost(uriBuilder.getHost(), uriBuilder.getPort(), uriBuilder.getScheme());
   List<NameValuePair> nameValuePairs = new ArrayList<>();
   nameValuePairs.add(new BasicNameValuePair("key1", "value1"));
   nameValuePairs.add(new BasicNameValuePair("key2", "value2"));
   String entityValue = URLEncodedUtils.format(nameValuePairs, StandardCharsets.UTF_8.name());
   StringEntity entity = new StringEntity(entityValue, StandardCharsets.UTF_8.name());
   post.setEntity(entity);
   httpClient.execute(target, post);
person user7294900    schedule 18.11.2019
comment
Tapi bukankah ini menggunakan isi permintaan dan bukan parameter permintaan? Ini adalah implementasi yang sangat berbeda. - person Mirrana; 18.11.2019
comment
@agent154 Lihat postMethod.addParameter https://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/methods/PostMethod.html#addParameter(java.lang.String,%20java.lang.String) Menambahkan parameter baru untuk digunakan dalam Isi permintaan POST. - person user7294900; 18.11.2019
comment
@agent154 solusi yang lebih sederhana adalah dengan menyandikan nilai postMethod.addParameter("key1", URLEncoder.encode("value1","UTF-8")); - person user7294900; 18.11.2019

Pertama-tama, Anda perlu memastikan bahwa string yang sebenarnya Anda tulis dikodekan dalam UTF-8. Saya menyadari bahwa Anda sudah mengetahuinya tetapi tetap periksa kembali apakah memang demikian, karena itu akan menjadi tersangka utama masalah Anda. Selain itu, saya akan merekomendasikan untuk mencoba klien HTTP yang lebih sederhana. Klien HTTP Apache (saya yakin itulah perpustakaan yang Anda gunakan) adalah perpustakaan yang luar biasa. Namun karena mencakup pilihan yang sangat luas, ini cenderung agak besar. Jadi, atau permintaan sederhana saya akan menyarankan klien HTTP ringan yang mungkin tidak selengkap perpustakaan Apache tetapi menawarkan kesederhanaan sebagai trade-off. Berikut tampilan kode Anda:

    private static void testHttpClient() {
        HttpClient client = new HttpClient();
//      client.setContentType("text/html; charset=utf-8");
        client.setContentType("application/json; charset=utf-8");
        client.setConnectionUrl("http://www.my-url.com");
        String content = null;
        try {
            String myMessage = getMyMessage() // get the string that you want to send
            content = client.sendHttpRequest(HttpMethod.POST, myMessage);
        } catch (IOException e) {
            content = client.getLastResponseMessage() + TextUtils.getStacktrace(e, false);
        }
        System.out.println(content);
    }

Kelihatannya jauh lebih sederhana, menurut saya. Juga di perpustakaan yang sama, ada utilitas lain yang memungkinkan Anda mengonversi string apa pun dalam bahasa apa pun menjadi rangkaian unicode dan sebaliknya. Ini membantu saya berkali-kali untuk mendiagnosis masalah pengkodean yang sulit. Misalnya, jika Anda melihat beberapa simbol omong kosong yang mungkin merupakan tampilan karakter valid yang salah atau hilangnya karakter sebenarnya. Berikut ini contoh cara kerjanya:

result = "Hello World";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);

Output dari kode ini adalah:

\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064
Hello World

Itu mungkin membantu Anda memeriksa apakah string yang Anda berikan valid atau tidak. Perpustakaannya disebut MgntUtils dan dapat ditemukan di Maven Central atau di Github Ini hadir sebagai artefak pakar dan dengan sumber serta Javadoc. Javadoc dapat ditemukan secara terpisah di sini
Penafian: Perpustakaan MgntUtils ditulis oleh saya

person Michael Gantman    schedule 18.11.2019