========================================================================
من الشائع جدًا ظهور أحرف مشوهة عند تطوير تطبيقات Java. بعد كل شيء، لا يتم استخدام Unicode على نطاق واسع الآن في النظام الذي يستخدم gb2312 (بما في ذلك gbk المبسط وbig5 التقليدي)،
وهو المتطلبات الأساسية لتنفيذ العرض الصيني بشكل صحيح. تخزين قاعدة البيانات.
=============================================================
1. أولاً، يجب على المطور أن يفهم سبب مواجهته للتعليمات البرمجية المشوهة ونوع التعليمات البرمجية المشوهة التي يواجهها (رموز لا معنى لها، أو سلسلة من علامات الاستفهام، أو أي شيء آخر).
عادة ما يكون المبتدئون في حيرة من أمرهم عندما يواجهون مجموعة من الأحرف الفوضوية. رد الفعل الأكثر مباشرة هو فتح Google والبحث عن "java Chinese" (يتم الاستعلام عن هذه السلسلة بشكل متكرر في محركات البحث)،
ثم إلقاء نظرة على أحرف الأشخاص الآخرين واحدًا تلو الآخر. حل واحد. ولا حرج في ذلك، ولكن تحقيق الهدف صعب، للأسباب المذكورة أدناه.
باختصار، هناك أسباب كثيرة للأحرف المشوهة، والحلول مختلفة تمامًا لحل المشكلة، يجب عليك أولاً تحليل "السياق" الخاص بك.
=====================
2. على وجه التحديد، ما هي المعلومات المطلوبة لتحديد مصدر التعليمات البرمجية المشوهة في المشروع.
أ.نظام التشغيل الذي يستخدمه المطور
ب، اسم وإصدار حاوية j2ee
c واسم قاعدة البيانات والإصدار (الإصدار الدقيق) وإصدار برنامج تشغيل jdbc
د. هناك كود مصدر مشوه (على سبيل المثال، يأتي من خارج النظام، أو يكون في صفحة jsp. إذا كان في jsp، فإن إعلان الرأس مهم جدًا أيضًا)
========== === =====================================================================================
3. كيفية التحليل الأولي لأسباب الحروف المشوهة.
باستخدام المعلومات المذكورة أعلاه، يمكنك النشر بشكل أساسي للحصول على المساعدة، وأعتقد أنه إذا قمت بوضعها في منتديات مثل Javaworld، فسوف يتوصل الخبراء قريبًا إلى حلول فعالة لك.
بالطبع، لا يمكنك دائمًا الاعتماد على النشر للحصول على المساعدة، ولكن يجب عليك أيضًا محاولة حل المشكلة بنفسك. كيف تبدأ؟
أ. قم بتحليل ما هو ترميز "الكود المشوه" الخاص بك. وهذا في الواقع ليس صعبا، على سبيل المثال
System.out.println(testString);
توجد تعليمات برمجية مشوهة في هذه الفقرة، لذا يمكنك أيضًا استخدام الطريقة الشاملة لتخمين تنسيق التشفير الفعلي الخاص بها.
System.out.println(new String(testString.getBytes("ISO-8859-1″),,"gb2312″));
System.out.println(new String(testString.getBytes("UTF8″),,"gb2312″));
System.out.println(new String(testString.getBytes("GB2312″),"gb2312″));
System.out.println(new String(testString.getBytes("GBK"),"gb2312"));
System.out.println(new String(testString.getBytes("BIG5"),"gb2312"));
انتظر، الكود أعلاه يعني استخدام تنسيق الترميز المحدد لقراءة "الكود المشوش" الخاص بـ testString وتحويله إلى gb2312 (يتم استخدام اللغة الصينية فقط كمثال هنا)
ثم ترى النتيجة التي تم تحويلها على ما يرام، هذا كل شيء. . .
ب. إذا تمكنت من الحصول على اللغة الصينية الصحيحة باستخدام الخطوات المذكورة أعلاه، فهذا يعني أن بياناتك موجودة بالتأكيد، ولكن لا يتم عرضها بشكل صحيح في الواجهة. ثم الخطوة الثانية هي تصحيح جزء العرض الخاص بك
. ما يجب التحقق منه عادةً هو ما إذا كان قد تم تحديد ترميز الصفحة الصحيح في ملف jsp.
أود أن أشير إلى شيء أسيء فهمه من قبل العديد من الأشخاص، وهو التوجيه <%@ page contentType="text/html; charset=GB2312″ %> و<META http-equiv=Content-Type
content="text /html; charset= gb2312″>الفرق بين الاثنين. عادةً عندما تشير العديد من المقالات على الإنترنت إلى المشكلات الصينية، يقولون إن اختيار تخزين unicode أو gb2312 في قاعدة البيانات يمكن حله
باستخدام
توجيه الصفحة في jsp لإعلان التشفير.لكنني أعتقد أن هذا البيان غير مسؤول للغاية، وقد جعلني أقضي الكثير من الوقت في حالة من الاكتئاب بشأن الرموز المشوهة التي لم تكن موجودة في المقام الأول. في الواقع، يتمثل دور الصفحة
في توفير طريقة ترميز لـ Java "لقراءة" السلسلة في التعبير أثناء عملية تجميع JSP إلى HTML (يشبه إلى حد ما دور العبارة الثالثة أعلاه)، ودور
الصفحة Meta معروف جيدًا أنه يوفر خيارات تشفير لمتصفحات IE، والتي تُستخدم "لعرض" البيانات النهائية. لكنني لم أر أي شخص يذكرني بهذا، لقد استخدمت دائمًا الصفحة كميتا،
مما أدى إلى قراءة البيانات التي كانت في الأصل ISO-8859 على أنها gb2312 بواسطة أمر الصفحة، لذلك كانت مشوهة، لذلك أضفت ترميزًا. وظيفة التحويل لتحويل جميع بيانات السلسلة لقد تغيرت جميعها من iso8859 إلى gb2312 (
لماذا
غيرتها بهذه الطريقة، لم أفكر كثيرًا في ذلك الوقت، لأنه يمكن عرضها بشكل طبيعي، لذلك قمت بتغييرها بهذه الطريقة، هاها). ، لم يكن لدي الوقت الكافي لاستكشاف المشكلة وإصلاحها ببطء في ذلك الوقت).================================================================================================== =============
4. ما هو الترميز الأفضل لقاعدة البيانات؟
تشتمل قواعد البيانات الشائعة حاليًا بشكل أساسي على SQL Server وmysql وOracle وDB2 وما إلى ذلك. ومن بينها، يعتبر MySQL الرائد بين قواعد البيانات المجانية وأدائه ووظائفه، وهو مناسب نسبيًا للتثبيت والتكوين، كما أن برنامج التشغيل
المقابل
مناسب أيضًا نسبة السعر/الأداء مطلقة. لذا خذ MySQL كمثال.
أنا شخصيا أوصي باستخدام الترميز الافتراضي لـ mysql للتخزين، وهو iso-8859-1 (المتوافق مع latin-1 في خيارات mysql). هناك عدة أسباب رئيسية. أولاً، يتمتع ISO-8859-1 بدعم جيد للغة
الصينية
. ثانيًا، يتوافق مع الترميز الافتراضي في Java، مما يزيل على الأقل مشكلة تحويل الترميز في العديد من الأماكن. ثالثًا، يكون الإعداد الافتراضي نسبيًا الاستقرار والمتوافقأفضل أيضًا، نظرًا لأنه
يتم توفير دعم الترميز المتعدد بواسطة منتجات قاعدة بيانات محددة، ناهيك عن عدم التوافق مع قواعد البيانات الأخرى، حتى الإصدارات المختلفة من نفسها قد تواجه مشكلات في التوافق.
على سبيل المثال، في المنتجات قبل mysql 4.0، تستخدم العديد من الحلول الصينية حقل تشفير الأحرف في الاتصال لتعيين التشفير، مثل gb2312 أو شيء من هذا القبيل، وهذا أمر جيد
لأن البيانات الأصلية مشفرة بـ ISO8859_1، وسيستخدم برنامج تشغيل jdbc البيانات المحددة. في عنوان url، يتم استخدام مجموعة الأحرف للتشفير، ويقوم resultSet.getString(*) بإخراج السلسلة المشفرة
. بهذه الطريقة، يمكنك الحصول مباشرة على بيانات gb2312.
ومع ذلك، فإن إطلاق MySQL 4.1 قد تسبب في الكثير من المتاعب للعديد من مسؤولي dbadmin، لأن MySQL 4.1 يدعم مجموعة أحرف مستوى العمود، ويمكن لكل جدول وعمود تحديد الترميز
. إذا لم يتم تحديده، فسيكون ISO8895_1، لذلك بعد إخراج jdbc البيانات، سيتم استخدامها على أساس العمود، ويتم استخدام مجموعة الأحرف للتشفير، بدلاً من استخدام معلمة عامة للحصول على كافة البيانات.
وهذا يظهر أيضًا من جانب آخر أن مشكلة الشخصيات المشوهة معقدة بالفعل ولها أسباب كثيرة. أنا فقط أقدم بعض الحلول للموقف الفعلي الذي واجهته. إذا كانت هناك أية
أخطاء
، يرجى إرسال بريد إلكتروني إلى [email protected] . وآمل أن أرى المزيد من مقالات الأستاذ بدلاً من مجموعة من النسخ المزيفة.
الاستخدام الداخلي فقط.
إذا كان لديك أي سؤال، يرجى الرجوع إلى [email protected]
================================================================================================== =============
وأخيرا وجدت الحل الأمثل للمشكلة الصينية. . . شكرا لمؤلف هذا المقال على الانترنت. . .
مقالتي الأصلية مبنية على تجربتي الخاصة. على الرغم من عدم وجود أي خطأ، لم يتم العثور على السبب الجذري النهائي للمشكلة. بعد قراءة هذا المقال أدركت فجأة: هههه
——————————————————————————————————————— ———— ——————-
نظرًا لأن المشكلة الصينية في برمجة Java هي مشكلة شائعة، فبعد قراءة العديد من الحلول لمشاكل Java الصينية، جنبًا إلى جنب مع ممارسة برمجة المؤلف، وجدت أن العديد من الأساليب التي تمت مناقشتها في الماضي لا يمكنها شرح المشكلة بوضوح المشكلة وحل المشكلة، وخاصة المشكلة الصينية عندما عبر منصة.
لذلك قدمت هذا المقال، الذي يتضمن تحليلي والحلول المقترحة للمشكلات الصينية في الفئات، وفئاتServets، وJSP، وEJB التي تعمل على وحدة التحكم. آمل أن تتمكن من إعطائي بعض النصائح.
الملخص: تحلل هذه المقالة بشكل عميق عملية ترميز/فك تشفير ملفات Java المصدرية بواسطة مترجم Java وملفات الفئة بواسطة JVM في برمجة Java، ومن خلال تحليل هذه العملية، تم الكشف أخيرًا عن السبب الجذري للمشاكل الصينية في برمجة Java نظرا للطريقة المثلى المقترحة لحل مشاكل جافا الصينية.
1. مصدر المشكلة الصينية
: كان التشفير الذي يدعمه نظام التشغيل الأصلي للكمبيوتر هو تشفير الأحرف أحادي البايت، لذلك تمت معالجة جميع برامج المعالجة في الكمبيوتر في البداية باللغة الإنجليزية بتشفير أحادي البايت.
مع تطور أجهزة الكمبيوتر، من أجل التكيف مع لغات الدول الأخرى في العالم (بما في ذلك بالطبع الأحرف الصينية)، اقترح الناس ترميز UNICODE، الذي يستخدم ترميز مزدوج البايت ومتوافق مع الأحرف الإنجليزية وترميزات الأحرف مزدوجة البايت للدول الأخرى، لذلك، تستخدم معظم البرامج الدولية حاليًا ترميز UNICODE داخليًا، عند تشغيل البرنامج، فإنه يحصل على تنسيق التشفير المدعوم افتراضيًا بواسطة نظام الدعم المحلي (في معظم الأحيان، نظام التشغيل). )، ثم يقوم بتحويل UNICODE داخل البرنامج إلى تنسيق الترميز الذي يدعمه النظام المحلي بشكل افتراضي.
هذا هو الحال بالنسبة لـ Java JDK وJVM. يشير JDK الذي أتحدث عنه هنا إلى الإصدار الدولي من JDK. يستخدم معظم المبرمجين لدينا إصدار JDK الدولي. الأحرف الصينية لدينا هي لغة ترميز مزدوجة البايت للسماح لأجهزة الكمبيوتر بمعالجة اللغة الصينية، قمنا بتطوير معاييرنا الخاصة مثل gb2312 وGBK وGBK2K لتلبية احتياجات معالجة الكمبيوتر.
لذلك، من أجل التكيف مع احتياجاتنا لمعالجة اللغة الصينية، قامت معظم أنظمة التشغيل بتخصيص أنظمة تشغيل صينية، وهي تستخدم تنسيقات التشفير GBK وGB2312 لعرض الأحرف الصينية بشكل صحيح. على سبيل المثال: يستخدم Windows الصيني ترميز GBK للعرض بشكل افتراضي. عند حفظ الملفات في Windows 2000 الصيني، فإن تنسيق الترميز المستخدم افتراضيًا لحفظ الملفات هو أيضًا GBK، أي أن الترميز الداخلي لكافة الملفات المحفوظة في Windows 2000 الصيني يستخدم GBK الترميز بشكل افتراضي ملاحظة: يتم توسيع GBK على أساس GB2312.
نظرًا لأن لغة Java تستخدم ترميز UNICODE داخليًا، فعند تشغيل برنامج Java، تكون هناك مشكلة في تحويل الإدخال والإخراج من ترميز UNICODE وتنسيق الترميز المقابل الذي يدعمه نظام التشغيل والمتصفح. إذا كان هناك خطأ في أي من الخطوات، فسيتم تشويه الأحرف الصينية المعروضة. هذه هي مشكلة Java الصينية الشائعة.
وفي الوقت نفسه، تعد Java لغة برمجة متعددة المنصات، مما يعني أن البرامج التي نكتبها لا يمكن تشغيلها على النوافذ الصينية فحسب، بل أيضًا على نظام Linux الصيني والأنظمة الأخرى، كما أنها مطلوبة للتشغيل على الأنظمة الإنجليزية وغيرها. كثيرًا ما نرى شخصًا ما ينقل برنامج Java مكتوبًا على نظام التشغيل Windows 2000 الصيني ليعمل على نظام Linux باللغة الإنجليزية). ستجلب عملية الزرع هذه أيضًا مشاكل صينية.
كما أن بعض الأشخاص يستخدمون أنظمة التشغيل الإنجليزية والمتصفحات الإنجليزية مثل IE لتشغيل البرامج ذات الأحرف الصينية وتصفح صفحات الويب الصينية، وهم لا يدعمون اللغة الصينية بأنفسهم وسيتسببون أيضًا في حدوث مشكلات باللغة الصينية.
تقوم جميع المتصفحات تقريبًا بتمرير المعلمات بتنسيق ترميز UTF-8 افتراضيًا بدلاً من الترميز الصيني، وبالتالي، ستكون هناك أيضًا مشكلات عند تمرير المعلمات الصينية، مما يؤدي إلى ظهور أحرف مشوهة.
باختصار، الجوانب المذكورة أعلاه هي المصادر الرئيسية للمشاكل الصينية في Java، ونطلق على المشاكل الناجمة عن عدم تشغيل البرنامج بشكل صحيح للأسباب المذكورة أعلاه: مشاكل Java الصينية.
2. تتضمن العملية التفصيلية لتحويل ترميز Java
الفئات التالية:
*الفئات التي تعمل مباشرة على وحدة التحكم (بما في ذلك فئات الواجهة المرئية)
*فئات كود JSP (ملاحظة: JSP هو أحد أشكال فئة Servlets)
*Servelets. class
* فئة EJB
* فئات الدعم الأخرى التي لا يمكن تشغيلها مباشرة
قد تحتوي ملفات الفئة هذه على سلاسل صينية، وغالبًا ما نستخدم الأنواع الثلاثة الأولى من برامج Java للتفاعل المباشر مع المستخدمين لأحرف الإخراج والإدخال، مثل: نستخدم JSP. ويحصل Servlet على الأحرف التي يرسلها العميل، وتتضمن هذه الأحرف أيضًا الأحرف الصينية. بغض النظر عن دور فئات Java هذه، فإن دورة حياة برامج Java هذه هي كما يلي:
*يختار المبرمجون برنامج تحرير مناسب على نظام تشغيل معين لتنفيذ كود البرنامج المصدر وحفظه في نظام التشغيل بامتداد .Java على سبيل المثال، نستخدم برنامج Notepad لتحرير برنامج مصدر Java في نظام التشغيل Windows 2000 الصيني.
*يستخدم المبرمجون Javac.exe في JDK لتجميع أكواد المصدر هذه لتكوين فئات .class (يتم تجميع ملفات JSP بواسطة الحاوية التي تستدعي JDK).
* قم بتشغيل هذه الفئات مباشرة أو نشرها في حاوية WEB لتشغيل النتائج وإخراجها.
إذن، أثناء هذه العمليات، كيف يمكن لـ JDK وJVM تشفير هذه الملفات وفك تشفيرها وتشغيلها؟
هنا، نأخذ نظام التشغيل Windows 2000 الصيني كمثال لتوضيح كيفية تشفير وفك تشفير فئات Java.
الخطوة الأولى هي استخدام برنامج التحرير مثل Notepad لكتابة ملف برنامج Java المصدر (بما في ذلك الأنواع الخمسة المذكورة أعلاه من برامج Java) في نظام التشغيل Windows 2000 الصيني. عند حفظ ملف البرنامج، يستخدم ملف البرنامج تنسيق ترميز GBK المدعوم من قبل نظام التشغيل افتراضيًا (يدعمه نظام التشغيل افتراضيًا). التنسيق هو تنسيق file.encoding) الذي يشكل ملف .Java، أي أنه قبل تجميع برنامج Java، يتم حفظ ملف برنامج Java المصدر في ملف .encoding تنسيق الترميز الذي يدعمه نظام التشغيل افتراضيًا، يحتوي برنامج Java المصدر على أحرف معلومات صينية ورموز برامج باللغة الإنجليزية، لعرض معلمة file.encoding الخاصة بالنظام، يمكنك استخدام الكود التالي:
public class ShowSystemDefaultEncoding.
{
الفراغ العام الثابت الرئيسي (String[] args)
{
ترميز السلسلة =
System.getProperty("file.encoding");
System.out.println(encoding);
}
}
في الخطوة الثانية، نستخدم ملف Javac.exe الخاص بـ JDK لتجميع برنامج مصدر Java الخاص بنا نظرًا لأن JDK هو إصدار دولي، عند التجميع، إذا لم نستخدم المعلمة -encoding لتحديد تنسيق التشفير لمصدر Java الخاص بنا. البرنامج، ثم يحصل Javac.exe أولاً على تنسيق الترميز الذي يستخدمه نظام التشغيل الخاص بنا افتراضيًا، أي عند تجميع برنامج Java، إذا لم نحدد تنسيق الترميز لملف البرنامج المصدر، فسيحصل JDK أولاً على المعلمة file.encoding. من نظام التشغيل (الذي يحفظ تنسيق الترميز الافتراضي، مثل Windows2000، وقيمته GBK)، ثم يقوم JDK بتحويل برنامج Java المصدر الخاص بنا من تنسيق ترميز file.encoding إلى تنسيق UNICODE الافتراضي الداخلي لـ Java ويضعه في الذاكرة.
بعد ذلك، يقوم Javac بتجميع ملف تنسيق Unicode المحول إلى ملف فئة .class. في هذا الوقت، يتم ترميز ملف .class بواسطة UNICODE، ويتم وضعه مؤقتًا في الذاكرة، ثم يقوم JDK بتجميع الفئة المترجمة في ترميز UNICODE يتم حفظه في نظام التشغيل الخاص بنا لتكوين ملف .class الذي نراه.
بالنسبة لنا، ملف .class الذي حصلنا عليه أخيرًا هو ملف فئة يتم حفظ محتواه بتنسيق ترميز UNICODE، ويحتوي على السلسلة الصينية في برنامجنا المصدر، ولكن في الوقت الحالي تم تحويله إلى تنسيق UNICODE من خلال تنسيق file.encoding. .
في هذه الخطوة، يختلف ملف البرنامج المصدر لـ JSP. بالنسبة لـ JSP، تكون العملية على النحو التالي: أي أن حاوية WEB تستدعي مترجم JSP أولاً يتحقق مما إذا كان تنسيق ترميز الملف قد تم تعيينه في ملف JSP لا يوجد تنسيق ترميز ملف في ملف JSP، لتعيين تنسيق ترميز ملف JSP، يستدعي مترجم JSP JDK لتحويل ملف JSP أولاً إلى فئة Servlet مؤقتة باستخدام تنسيق ترميز الأحرف الافتراضي لـ JVM (أي الافتراضي file.encoding لنظام التشغيل حيث توجد حاوية WEB)، ثم يتم تجميعه في فئة تنسيق UNICODE وحفظه في مجلد مؤقت.
على سبيل المثال: في نظام التشغيل Windows 2000 الصيني، تقوم حاوية WEB بتحويل ملف JSP من تنسيق ترميز GBK إلى تنسيق UNICODE، ثم تقوم بتجميعه في فئة Servlet محفوظة مؤقتًا للاستجابة لطلب المستخدم.
الخطوة الثالثة هي تشغيل الفصل الذي تم تجميعه في الخطوة الثانية، والذي ينقسم إلى ثلاث حالات:
A. الفئات التي تعمل مباشرة على وحدة التحكم
B. فئات EJB وفئات الدعم التي لا يمكن تشغيلها مباشرة (مثل فئات JavaBean)
C. كود JSP وفئات Servlet
D. بين برامج Java وقواعد البيانات
دعونا نلقي نظرة على هذه المواقف الأربعة أدناه.
ج: في حالة وجود فئة يتم تشغيلها مباشرة على وحدة التحكم
، فإن تشغيل هذه الفئة يتطلب أولاً دعم JVM، أي أنه يجب تثبيت JRE في نظام التشغيل. عملية التشغيل هي كما يلي: أولاً، تقوم Java بتشغيل JVM. في هذا الوقت، يقرأ JVM ملف الفئة المحفوظ في نظام التشغيل ويقرأ المحتوى في الذاكرة. في هذا الوقت، تكون الذاكرة فئة تنسيق UNICODE. ثم يقوم JVM بتشغيله إذا احتاجت هذه الفئة في هذا الوقت إلى تلقي إدخالات المستخدم، فستستخدم الفئة تنسيق ترميز file.encoding افتراضيًا لتشفير إدخال السلسلة من قبل المستخدم وتحويلها إلى Unicode وحفظها في الذاكرة. (يمكن للمستخدم ضبط تنسيق الترميز لدفق الإدخال).
بعد تشغيل البرنامج، يتم إرجاع السلسلة التي تم إنشاؤها (بترميز UNICODE) إلى JVM وأخيرًا، يقوم JRE بتحويل السلسلة إلى تنسيق file.encoding (يمكن للمستخدم تعيين تنسيق الترميز لدفق الإخراج) ويمررها إلى نظام التشغيل. واجهة العرض وإخراجها إلى الواجهة. تتطلب كل خطوة من خطوات التحويل المذكورة أعلاه تحويل تنسيق التشفير الصحيح بحيث لا تظهر الأحرف المشوهة في النهاية. ب. فئات EJB وفئات الدعم التي لا يمكن تشغيلها مباشرة (مثل فئات JavaBean)
نظرًا لأن فئات EJB وفئات الدعم التي لا يمكن تشغيلها بشكل مباشر، فإنها لا تتفاعل بشكل عام مع المستخدمين مباشرةً للإدخال والإخراج للإدخال والإخراج، لذلك بعد تجميعها في الخطوة الثانية، فإنها تشكل فئة يكون محتواها ترميز UNICODE ويتم حفظها في نظام التشغيل في المستقبل، طالما أن التفاعل بينها وبين الفئات الأخرى ليس كذلك إذا فقدت أثناء عملية تمرير المعلمة، فسيتم تشغيلها بشكل صحيح.
ج.
بعد الخطوة الثانية من كود JSP وفئة Servlet، يتم أيضًا تحويل ملف JSP إلى ملف فئة Servlets، ولكنه غير موجود في دليل الفئات مثل Servlets القياسية، فهو موجود في الدليل المؤقت لحاوية WEB ، لذلك في هذه الخطوة ننظر إليها أيضًا على أنها Servlets.
بالنسبة إلى Servlets، عندما يطلب العميل ذلك، تستدعي حاوية WEB JVM الخاصة بها لتشغيل Servlet. أولاً، يقرأ JVM فئة Servlet من النظام ويقوم بتحميلها في الذاكرة، وهو رمز فئة Servlet المشفر UNICODE.ثم يقوم JVM بتشغيل فئة Servlet في الذاكرة. إذا كان Servlet قيد التشغيل، فإنه يحتاج إلى قبول الأحرف من العميل، مثل القيم المدخلة في النموذج والقيم التي تم تمريرها في عنوان URL الوقت، إذا لم يتم تعيين البرنامج للقبول إذا تم استخدام تنسيق الترميز كمعلمة، فستستخدم حاوية WEB تنسيق الترميز ISO-8859-1 افتراضيًا لقبول القيمة الواردة وتحويلها إلى تنسيق UNICODE في JVM و احفظه في ذاكرة حاوية WEB.
بعد تشغيل Servlet، يقوم بإنشاء الإخراج، وتكون سلسلة الإخراج بتنسيق UNICODE، ثم ترسل الحاوية مباشرة سلسلة تنسيق UNICODE (مثل بناء جملة HTML، وسلسلة إخراج المستخدم، وما إلى ذلك) التي تم إنشاؤها بواسطة تشغيل Servlet إلى العميل. المتصفح وإخراجه إلى إذا حدد المستخدم تنسيق الترميز للإخراج عند الإرسال في هذا الوقت، فسيتم إخراجه إلى المتصفح بتنسيق الترميز المحدد إذا لم يتم تحديده، فسيتم إرساله إلى متصفح العميل في ISO-8859-. 1 الترميز الافتراضي.
د. بين برنامج Java وقاعدة البيانات
بالنسبة لجميع برامج تشغيل JDBC لقاعدة البيانات تقريبًا، فإن تنسيق التشفير الافتراضي لنقل البيانات بين برنامج Java وقاعدة البيانات هو ISO-8859-1، لذلك يقوم برنامجنا بنقل البيانات إلى قاعدة البيانات عند تخزين البيانات التي تحتوي على اللغة الصينية البرنامج، يقوم JDBC أولاً بتحويل البيانات بتنسيق ترميز UNICODE داخل البرنامج إلى تنسيق ISO-8859-1، ثم يمررها إلى قاعدة البيانات عندما تحفظ قاعدة البيانات البيانات، يتم حفظها بشكل افتراضي على ISO-8859-1، ولهذا السبب فإن البيانات الصينية التي نقرأها غالبًا في قاعدة البيانات مشوهة.
3. العديد من المبادئ التي يجب فهمها عند تحليل مشكلات Java الصينية الشائعة
أولاً، بعد التحليل التفصيلي أعلاه، يمكننا أن نرى بوضوح أنه في دورة حياة أي برنامج Java، تكون العملية الرئيسية لتحويل التشفير هي: تجميعها في البداية في فئة. ملف إخراج عملية التحويل والتحويل النهائي للمستخدم.
ثانيًا، يجب أن نفهم أن تنسيقات التشفير الشائعة الاستخدام التالية التي تدعمها Java في وقت الترجمة هي:
*ISO-8859-1، 8 بت، نفس 8859_1، ISO-8859-1، ISO_8859_1 والترميزات الأخرى
*Cp1252، أمريكي ترميز اللغة الإنجليزية، نفس ترميز ANSI القياسي
*UTF-8، نفس ترميز Unicode
*GB2312، نفس gb2312-80، gb2312-1980 والترميزات الأخرى
*GBK، نفس MS936، وهو امتداد لـ gb2312 و ترميزات أخرى، مثل الكورية واليابانية والصينية التقليدية وما إلى ذلك. وفي الوقت نفسه، يجب الانتباه إلى علاقة التوافق بين هذه الترميزات على النحو التالي:
يوجد تطابق بين Unicode وUTF-8. يمكن اعتبار GB2312 مجموعة فرعية من GBK، أي أن تشفير GBK موسع على gb2312. في الوقت نفسه، يحتوي ترميز GBK على 20902 حرفًا صينيًا، ونطاق التشفير هو: 0×8140-0xfefe، ويمكن تعيين جميع الأحرف إلى UNICODE2.0 واحد لواحد.
ثالثًا، بالنسبة لملف البرنامج المصدر .Java الموجود في نظام التشغيل، أثناء التجميع، يمكننا تحديد تنسيق التشفير لمحتواه، وتحديدًا باستخدام -encoding. ملاحظة: إذا كان البرنامج المصدر يحتوي على أحرف صينية واستخدمت -encoding لتحديد أحرف ترميز أخرى، فمن الواضح أنه سيحدث خطأ.
استخدم -encoding لتحديد طريقة ترميز الملف المصدر كـ GBK أو gb2312. بغض النظر عن النظام الذي نقوم بتجميع برنامج Java المصدر الذي يحتوي على أحرف صينية عليه، فلن تكون هناك مشكلة في تحويل اللغة الصينية بشكل صحيح إلى UNICODE وتخزينها في ملف ملف الصف.
بعد ذلك، يجب أن نوضح أن تنسيق ترميز الأحرف الافتراضي لجميع حاويات WEB تقريبًا يستخدم ISO-8859-1 كقيمة افتراضية. وفي الوقت نفسه، تستخدم جميع المتصفحات تقريبًا UTF-8 بشكل افتراضي عند تمرير المعلمات .
لذلك، على الرغم من أن ملف Java المصدر الخاص بنا يحدد طريقة التشفير الصحيحة عند الإدخال والخروج، إلا أنه لا يزال تتم معالجته كـ ISO-8859-1 عند تشغيله داخل الحاوية.
4. تصنيف المشاكل الصينية والحلول الأمثل الموصى بها
بعد فهم المبادئ المذكورة أعلاه لمعالجة ملفات جافا، يمكننا طرح مجموعة من الحلول المثالية المقترحة لمشاكل الأحرف الصينية. هدفنا هو: يمكن ترحيل برامج Java المصدرية التي تحتوي على سلاسل صينية أو معالجة صينية نقوم بتحريرها في النظام الصيني إلى أي نظام تشغيل آخر للعمل بشكل صحيح بعد التجميع، أو يمكن تجميعها في أنظمة تشغيل أخرى، ويمكن تشغيلها بشكل صحيح اجتياز المعلمات الصينية والإنجليزية، ويمكنه توصيل السلاسل الصينية والإنجليزية بشكل صحيح مع قاعدة البيانات. فكرتنا المحددة هي تقييد طريقة التشفير لجعلها صحيحة عند الدخول والخروج من تحويل ترميز برنامج Java وحيث يكون لبرنامج Java تحويل المدخلات والمخرجات مع المستخدم.
الحلول المحددة هي كما يلي:
1. بالنسبة للفئات التي تعمل مباشرة على وحدة التحكم
، في هذه الحالة، نوصي أنه عند كتابة برنامج، إذا كنت بحاجة إلى تلقي مدخلات من المستخدم قد تحتوي على اللغة الصينية أو المخرجات التي قد تحتوي على اللغة الصينية، يجب أن يستخدم البرنامج تدفقات الأحرف المستخدمة للتعامل مع الإدخال والإخراج، على وجه التحديد، يتم تطبيق أنواع دفق العقدة الموجهة نحو الأحرف التالية:
بالنسبة للملفات: FileReader، FileWrieter،
أنواع دفق العقدة الموجهة بالبايت هي: FileInputStream، FileOutputStream
للذاكرة (الصفيف). ): CharArrayReader،
CharArrayWriter أنواع دفق العقدة هي: ByteArrayInputStream، ByteArrayOutputStream.
Memory (string): StringReader، StringWriter
Pipes
: PipedReader، PipedWriter.
أنواع دفق عقدة البايت هي: PipedInputStream، PipedOutputStream.
يجب استخدام تدفقات المعالجة الموجهة للإدخال والإخراج:
BufferedWriter وBufferedReader،
وتدفقات المعالجة من نوع البايت هي: BufferedInputeStream وBufferedOutputStream
InputStreamReader وOutputStreamWriter،
وتدفقات المعالجة من نوع البايت هي: DataInputStream وDataOutputStream
وInputStreamWriter تحويل دفق البايت وفقًا لمجموعة ترميز الأحرف المحددة، مثل:
InputStreamReader in = new InputStreamReader(System.in, "GB2312"); OutputStreamWriter out = new OutputStreamWriter (System.out, "GB2312"); مثال: نموذج ترميز Java التالي يمكن أن يلبي المتطلبات:
//Read.Java
استيراد Java.io.*;
قراءة الطبقة العامة
{
الفراغ العام الثابت الرئيسي (String[] args)
throwsIOException
{
سلسلة سلسلة =
"nاختبار اللغة الصينية، هذه هي السلسلة الداخلية المشفرة "+"nاختبار الحرف الإنجليزي";
سلسلة السلسلة = ""؛
BufferedReader stdin =
قارئ مؤقت جديد (جديد
InputStreamReader(System.in,"gb2312″));
// قم بتعيين واجهة الإدخال المراد تشفيرها باللغة الصينية
BufferedWriter stdout =
كاتب مؤقت جديد(new
OutputStreamWriter(System.out,"gb2312″));
// قم بتعيين واجهة الإخراج المراد تشفيرها باللغة الصينية
stdout.write("الرجاء إدخال:");
stdout.flush();
strin = stdin.readLine();
stdout.write("هذا هو إدخال السلسلة من المستخدم:"+strin);
stdout.write(str);
stdout.flush();
}}
في الوقت نفسه، عند تجميع البرنامج، نستخدم الطريقة التالية:
Javac -encoding gb2312 Read.Java
2. بالنسبة لفئات EJB وفئات الدعم التي لا يمكن تشغيلها مباشرة (مثل فئة JavaBean)،
لأن هذه الفئات نفسها يتم استخدامها من قبل فئات أخرى. لا يتفاعل الاستدعاء مباشرة مع المستخدم، لذلك بالنسبة لهذا النوع، فإن طريقة المعالجة الموصى بها هي أن البرنامج الداخلي يجب أن يستخدم تدفقات الأحرف لمعالجة السلاسل الصينية داخل البرنامج (على وجه التحديد كما في القسم أعلاه)، وفي الوقت نفسه، عند تجميع الفصل، استخدم المعلمة -encoding gb2312 للإشارة إلى أن الملف المصدر مشفر بالتنسيق الصيني.
3. بالنسبة لفئة Servlet
، نوصي بالطريقة التالية:
عند تجميع البرنامج المصدر لفئة Servlet، استخدم -encoding لتحديد التشفير كـ GBK أو GB2312، واستخدم setContentType("text" لكائن الاستجابة في التشفير عند الإخراج إلى المستخدم /html;charset=GBK”); أو gb2312 لتعيين تنسيق ترميز الإخراج. وبالمثل عند تلقي إدخال المستخدم، نستخدم request.setCharacterEncoding(”GB2312″); يتم نقل فئة servlet الخاصة بنا إلى العميل فقط. إذا كان متصفحك يدعم العرض الصيني، فسيتم عرضه بشكل صحيح. هنا مثال صحيح:
//HelloWorld.Java
مرحبا الحزمة؛
استيراد Java.io.*;
استيراد Javax.servlet.*;
import Javax.servlet.http.*;
الطبقة العامة HelloWorld
يمتد HttpServlet
{
الحرف الأول الفراغي العام ()
يلقي ServletException
{
}
الفراغ العام doGet
(طلب HttpServletRequest،
استجابة HttpServletResponse)
يلقي IOException، ServletException
{
request.setCharacterEncoding("GB2312");
//تعيين تنسيق ترميز الإدخال
Response.setContentType
("text/html;charset=GB2312");
// قم بتعيين تنسيق ترميز الإخراج
PrintWriter out = Response.getWriter();
// يوصى باستخدام مخرجات PrintWriter
println("<hr>");
out.println("مرحبًا بالعالم!
تم إنشاء هذا بواسطة Servlet!اختبار اللغة الصينية!");
println("<hr>");
}
doPost باطلة عامة (طلب HttpServletRequest،
استجابة HttpServletResponse)
يلقي IOException، ServletException
{
request.setCharacterEncoding("GB2312");
// تعيين تنسيق ترميز الإدخال
Response.setContentType
("text/html;charset=GB2312");
// قم بتعيين تنسيق ترميز الإخراج
اسم السلسلة = request.getParameter("name");
معرف السلسلة = request.getParameter("id");
إذا (الاسم == فارغ) الاسم = ""؛
إذا (معرف==فارغ) معرف = ""؛
PrintWriter out = Response.getWriter();
// يوصى باستخدام مخرجات PrintWriter
println("<hr>");
out.println("السلسلة الصينية التي قمت بإدخالها هي:" + name);
out.println("<hr>المعرف الذي أدخلته هو:" + id);
println("<hr>");
}
تدمير الفراغ العام ()
{
}
}
الرجاء استخدام Javac -encoding gb2312 HelloWorld.Java لتجميع هذا البرنامج.
برنامج اختبار هذا Servlet هو كما يلي:
< %@page contentType="text/html;
مجموعة الأحرف=gb2312″%>
<%request.setCharacterEncoding("GB2312");%>
<html><head><title></title>
<لغة البرنامج = "JavaScript">
وظيفة إرسال ()
{
// قم بتمرير قيمة السلسلة الصينية إلى Servlet من خلال عنوان URL
document.base.action =
"./HelloWorld?name=中文";
document.base.method = "POST"؛
document.base.submit();
}
</ سكريبت>
</head>
<body bgcolor=”#FFFFFF”
النص =”#000000″ الهامش العلوي=”5″>
طريقة <form name = "base" =
"POST" الهدف = "_self">
< اسم الإدخال = "معرف" نوع = "نص"
القيمة = "" الحجم = "30">
<a href = "JavaScript:Submit()">
انتقل إلى Servlet</a>
</form></body></html>
4.
لتجنب البيانات المشوهة في نقل البيانات بين برنامج Java وقاعدة البيانات، نوصي بالطرق المثلى التالية للتعامل معها:
1. يجب معالجة برنامج Java حسب الطريقة المحددة من قبلنا.
2. قم بتغيير تنسيق الترميز الذي تدعمه قاعدة البيانات افتراضيًا إلى GBK أو GB2312.
على سبيل المثال: في mysql، يمكننا إضافة العبارة التالية إلى ملف التكوين my.ini لتحقيق ذلك:
أضف:default-character-set=gbk
في منطقة [mysqld]
وأضف:
[client]
default-character-set=gbk
في SQL Server2K، يمكننا ضبط اللغة الافتراضية لقاعدة البيانات على اللغة الصينية المبسطة لتحقيق الغرض.
5. بالنسبة إلى كود JSP،
نظرًا لأن JSP يتم تجميعه ديناميكيًا بواسطة حاوية WEB في وقت التشغيل، إذا لم نحدد تنسيق التشفير لملف مصدر JSP، فسيحصل مترجم JSP على قيمة ترميز الملف لنظام تشغيل الخادم لتجميع نعم، من المرجح أن يسبب مشاكل عند الزرع. على سبيل المثال، ملف jsp الذي يمكن تشغيله بشكل جيد في نظام التشغيل Windows 2000 الصيني لن يعمل في Linux الإنجليزي، على الرغم من أن العملاء متماثلون ملف JSP عند تجميعه، يحدث بسبب ترميزات مختلفة لأنظمة التشغيل (يختلف file.encoding باللغة الصينية عن file.encoding في Linux الإنجليزي، كما أن file.encoding في Linux الإنجليزي لا يدعم اللغة الصينية، لذلك ستكون هناك مشاكل في فئة JSP المترجمة).
معظم المشكلات التي تمت مناقشتها على الإنترنت هي مشكلات من هذا القبيل، ويرجع ذلك في الغالب إلى عدم إمكانية عرض ملف JSP بشكل صحيح عند نقله إلى النظام الأساسي. بالنسبة لهذا النوع من المشكلات، فإننا نفهم مبدأ تحويل ترميز البرنامج في Java، وهو أسهل بكثير حلها. حلولنا المقترحة هي كما يلي:
1. يجب علينا التأكد من أن JSP يتم إخراجه بالتشفير الصيني عند الإخراج إلى العميل، أي بغض النظر عن ذلك، نقوم أولاً بإضافة السطر التالي إلى كود مصدر JSP الخاص بنا:
< %@page contentType =” نص/أتش تي أم أل؛
charset=gb2312″%>
2. من أجل السماح لـ JSP بالحصول على المعلمات الواردة بشكل صحيح، أضفنا الجملة التالية إلى رأس ملف مصدر JSP:
<%request.setCharacterEncoding(”GB2312″);
٪>
3. لكي يفكّر برنامج JSP بشكل صحيح ملفات JSP التي تحتوي على أحرف صينية ، نحتاج إلى تحديد تنسيق ترميز ملفات JSP الخاصة بنا في ملفات مصدر JSP. ملفات المصدر في رأس ملف JSP
.
أو < ٪@page pageencoding = "gbk" ٪>
هذا تعليمات تمت إضافتها حديثًا في مواصفات JSP 2.0.
نوصي باستخدام هذه الطريقة لحل المشكلات الصينية في ملفات JSP
.
< ٪@page pageencoding = "GB2312 ″ ٪>
< ٪@page contentType = "text/html ؛
charset = gb2312 ″ ٪>
<٪ request.setcharacterencoding ("GB2312") ؛
%>
<%
سلسلة الإجراء = request.getParameter ("الإجراء") ؛
اسم السلسلة = "" ؛
سلسلة str = "" ؛
if (Action! = null && action.equals ("send"))
{
name = request.getParameter ("name") ؛
str = request.getParameter ("str") ؛
}
%>
<أتش تي أم أل>
<الرأس>
<العنوان></العنوان>
<script language = "javaScript">
إرسال الوظيفة ()
{
document.base.action =
"؟؟ Action = send & str = الصينية الواردة" ؛
document.base.method = "post" ؛
document.base.submit () ؛
}
</ سكريبت>
</الرأس>
<body bgcolor = "#ffffff"
text = "#000000 ″ topmargin =" 5 ″>
<form name = "base" method =
"post" target = "_ self">
<type type = "text" name = "name"
value = "" size = "30 ″>
<a href = "javaScript: submit ()"> إرسال </a>
</النموذج>
<%
if (Action! = null && action.equals ("send"))
{
Out.println ("<br> الأحرف التي أدخلتها هي:"+name) ؛
Out.println ("<br> الشخصيات التي مررت بها عبر عنوان URL هي:"+str) ؛
}
%>
</الجسم>
</html>