Jika ada teman yang mengatakan bahwa dia belum mengalami masalah kode kacau Cina, saya tidak ingin mempercayainya. Hari ini, ketika saya membuat balasan cerdas ke akun langganan WeChat, saya melompat ke lubang api kode kacau Cina dengan cara yang bingung. Ketika saya pertama kali menyelesaikan masalah, saya bersorak dan benar -benar melupakan rasa sakit yang pernah dia bawa kepada saya.
1. Deskripsi Masalah
Melihat itu, kode -kode kacau di bingkai merah itu memicu saya, tetapi saya tidak berdaya. Itu sangat buruk.
2. Mencari solusi
Saat menghadapi masalah, Anda hanya bisa memaksa diri Anda untuk menyelesaikannya dengan pisau. Apa yang bisa kamu lakukan?
Pertama -tama, kita harus memahami mekanisme balasan cerdas WeChat, dan menggambar gambar sebagai berikut:
PS, mohon maaf karena tidak menggunakan alat dengan baik.
Selanjutnya, mari kita fokus pada poin -poin penting dan lihat di mana kode yang kacau itu penting.
1. Pengontrol kembali ke pengguna
response.setHeader ("tipe konten", "teks/html; charset = utf-8"); // browser encoding response.getoutputStream (). write (result.getbytes ());Hanya kode ini, metode pengkodean untuk menentukan responsnya adalah UTF-8. Adalah logis bahwa masalah yang kacau seharusnya membaik, tetapi hasilnya masih belum.
2.JAXB's ToxML
Public String Toxml (objek obj) {string result = null; coba {JAXBContext Context = JaxBContext.NewInstance (obj.getClass ()); Marshaller M = Context.CreateMarShaller (); M.SetProperty (Marshaller.jaxb_encoding, "UTF-8"); M.SetProperty (Marshaller.jaxb_formatted_output, true); M.SetProperty (Marshaller.jaxb_fragment, true); // Hapus header pesan bytearrayoutputStream os = bytearrayoutputStream (); Xmlserializer serializer = getXmlserializer (OS); M.Marshal (OBJ, Serializer.ascontenthandler ()); hasil = os.toString ("UTF-8"); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Teks Respons:" + hasil); Hasil pengembalian;} private xmlserializer getXmlserializer (outputStream OS) {outputFormat dari = outputFormat baru (); formatcdataTag (); of.setcdataelement (cDatanode); of.setPreservespace (true); Of.setindenting (true); dari.setomitxmldeclaration (true); dari.setencoding ("UTF-8"); Xmlserializer serializer = xmlserializer baru (OF); Serializer.setoutputByTestream (OS); return serializer;} Berikut adalah tiga poin utama:
1. M.SetProperty (Marshaller.jaxb_encoding, "UTF-8");
2. GetXmlSerializer (OS)
3. Os.ToString ("UTF-8");
Anda dapat melihat bahwa ketiga tempat di atas melibatkan transkode. Pertama -tama, atur penyandian marshaller; Di tempat kedua, atur seluruh pengkodean XMLSerializer; Di tempat ketiga, atur penyandian string dari ByteArrayOutputStream yang dikembalikan. Ketiganya sangat diperlukan.
Kali ini, itu seharusnya menyelesaikan masalah, tetapi solusinya masih dalam bentuk kacau Cina. Jadi apa yang harus saya lakukan?
3. Lingkungan output Tomcat salah
Menanggapi hal ini, seseorang secara online memberikan solusi seperti itu.
Setel java_opts =% java_opts% logging_manager% -dfile.encoding = UTF -8
Setelah mengatur, memulai kembali Tomcat, masalahnya adalah bahwa itu dapat diselesaikan, tetapi efek sampingnya adalah bahwa seluruh Tomcat menjalankan output pada server (jendela CMD Tomcat) selalu dibumbui, dan saya pikir solusi ini tidak disarankan.
Tambahkan kode berikut ke perang berjalan
System.getProperty ("File.encoding");Anda akan terkejut menemukan bahwa lingkungan Tomcat (Window Server 2008) ternyata menjadi GBK. Saya ingin tahu apakah Anda tidak terkejut. Saya takut, mengapa itu bukan UTF-8? Jika GBK, saya akan menambahkan lebih banyak halaman UTF-8 ke dua langkah di atas, dan saya tidak mengerti.
3. Selesaikan masalahnya
Dengan pengalaman di atas, kami memodifikasi kode WeChat4J berikut, terutama poin kedua.
Public String Toxml (objek obj) {string result = null; coba {JAXBContext Context = JaxBContext.NewInstance (obj.getClass ()); Marshaller M = Context.CreateMarShaller (); String encoding = config.instance (). GetJAXB_encoding (); logger.debug ("toxml encoding" + encoding + "sistem file.encoding" + system.getProperty ("file.encoding")); M.SetProperty (Marshaller.jaxb_encoding, encoding); M.SetProperty (Marshaller.jaxb_formatted_output, true); M.SetProperty (Marshaller.jaxb_fragment, true); // Hapus header pesan bytearrayoutputStream os = bytearrayoutputStream (); Xmlserializer serializer = getXmlserializer (OS); M.Marshal (OBJ, Serializer.ascontenthandler ()); hasil = os.tostring (pengkodean); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Teks Respons:" + hasil); Hasil pengembalian;} private xmlserializer getXmlserializer (outputStream OS) {outputFormat dari = outputFormat baru (); formatcdataTag (); of.setcdataelement (cDatanode); of.setPreservespace (true); Of.setindenting (true); dari.setomitxmldeclaration (true); String encoding = config.instance (). GetJAXB_encoding (); dari.setencoding (pengkodean); Xmlserializer serializer = xmlserializer baru (OF); Serializer.setoutputByTestream (OS); return serializer;}Di antara dua metode ini, kami menambahkan metode pengkodean yang dapat dikonfigurasi untuk secara otomatis mengatur GBK (GBK dikonfigurasi di server saya), GB2312, dan UTF-8.
Dengan cara ini, Anda akan menemukan bahwa output latar belakang WeChat4J tidak lagi dalam bentuk kacau Cina, tetapi informasi yang dikembalikan kepada pengguna bahkan lebih berantakan.
Bagaimana ini bisa dilakukan? Saya seorang programmer dan saya benar -benar ingin bersumpah beberapa kata bersumpah. Tapi jangan takut. Karena log logger WeChat4J tidak lagi dalam bentuk kacau Cina, hanya dapat dikatakan bahwa ada masalah lain di tahap pertama.
Menyesuaikan
response.setHeader ("tipe konten", "teks/html; charset = utf-8"); // browser encoding response.getoutputStream (). write (result.getbytes ("UTF-8")); Perhatikan bahwa ini tidak dapat berupa GBK, hanya UTF-8. Saya bilang saya tidak tahu mengapa, manajer produk WeChat memberikan penjelasan.
Poin kuncinya adalah bahwa JAXB dan respons bersama -sama menyelesaikan kode -kode kacau Cina WeChat4J dinyatakan sebagai berikut:
Wechatcontroller.java adalah url yang Anda alokasikan untuk platform pengembangan publik WeChat. Respons disesuaikan sebagai berikut
response.setHeader ("tipe konten", "teks/html; charset = utf-8"); // browser encoding response.getoutputStream (). write (result.getbytes ("UTF-8"));WeChat4J dari jaxbparser.java, sesuaikan metode TOXML (objek OBJ) dan getxmlserializer (OutputStream OS) masing -masing:
Public String Toxml (objek obj) {string result = null; coba {JAXBContext Context = JaxBContext.NewInstance (obj.getClass ()); Marshaller M = Context.CreateMarShaller (); String encoding = config.instance (). GetJAXB_encoding (); // gbk logger.debug ("toxml encoding" + encoding + "sistem file.encoding" + system.getProperty ("file.encoding"))); M.SetProperty (Marshaller.jaxb_encoding, encoding); M.SetProperty (Marshaller.jaxb_formatted_output, true); M.SetProperty (Marshaller.jaxb_fragment, true); // Hapus header pesan bytearrayoutputStream os = bytearrayoutputStream (); Xmlserializer serializer = getXmlserializer (OS); M.Marshal (OBJ, Serializer.ascontenthandler ()); hasil = os.tostring (pengkodean); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Teks Respons:" + hasil); Hasil pengembalian;} private xmlserializer getXmlserializer (outputStream OS) {outputFormat dari = outputFormat baru (); formatcdataTag (); of.setcdataelement (cDatanode); of.setPreservespace (true); Of.setindenting (true); dari.setomitxmldeclaration (true); String encoding = config.instance (). GetJaxB_encoding (); // gbk of.setencoding (encoding); Xmlserializer serializer = xmlserializer baru (OF); Serializer.setoutputByTestream (OS); return serializer;} Oke, semuanya berjalan dengan baik.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.