פיתרונות ב-JSP לקידוד עברית ב-UNICODE עם MySQL

‏ • 24 במרץ, 2005

הקדמה

אז מה? מנסים להתחבר לשרת MySQL ולשלוף נתונים בעברית וכל מה שיוצא זה סימני שאלה? טוב, זה בטח משהו בקידוד, אבל להבין ולסדר את הבעיה צריך לחפור קצת יותר עמוק לעולם הקידודים של JSP.



למה זה בכלל קורה?

כשבונים אתרים ב- PHP או ב- ASP, בדרך כלל לא אכפת למתכנתים איך הקידוד של האתר עובד. תכל'ס שמים איזה פקודת קידוד בתחילת העמוד והכל יוצא טוב. אז למה ב- JSP תמיד יש בעיות עם זה? שאלה טובה…

רוב האתרים בישראל עובדים בקידוד רגיל, כלומר ISO-8859-8 או windows-1255. קידוד זה אומר לדפדפנים שמגיעים לאתר שזהו אתר בעברית. ברוב המקרים אין עם הקידוד הזה בעיה וזה מספיק. אבל מה קורה שרוצים להכניס, נגיד כמה שפות לאותו העמוד? זה בעייתי.

אי-אפשר להגיד לדפדפן שכאן יש סינית, בצד שמאל יש עברית, ולמטה כתוב ביפנית. יש הגדרת קידוד אחת והיא קובעת. עוד בעיה עם הקידוד הרגיל, הוא במאגר נתונים, התווים שנשמרים הם לא עברית אמיתית. זה בעצם תווים באנגלית שמומרים לעברית ברגע שהדפדפן רואה אותם. מה קורה אם אתה עובר להשתמש במאגר נתונים עם שפת תכנות שלא מכירה מה זה ISO-8859-8? מסתבר שיוצא סימני שאלה.

על מנת לפתור את הבעיה הזאת בשביל זה המציאו לפני כמה שנים את תקן Unicode.

Unicode מיועד להיות הקידוד שיכיל בסופו של דבר את כל השפות שקיימות בעולם (וגם שפות שלא מהעולם הזה). בעזרת שימוש ב- 16 ביטים לשמירת כל אות, Unicode מאפשר לקודד יותר מ- 65,000 אותיות בקידוד יחיד. לדוגמא, קידוד ASCII מאפשר לקודד 256 סימנים. נשמע מעט, לא? Unicode גם מאפשר לתקשר בין מחשבים, פלטפורמות וכדומה בצורה אוניברסיאלית וללא חשש לטעויות בהעברה ולקבלת נתונים כסימני שאלה או בקידוד לא מתאים לשפה.

למזלנו, JSP מבוססת על JAVA. ו- JAVA עובדת בתקן של Unicode. כל מחרוזת (String) שאתם כותבים ב- JAVA נשמרת בזיכרון בקידוד Unicode כברירת מחדל. זה כמובן גם משפיע על התקשורת של מאגרי הנתונים, כי בעצם הנתונים שאתם מוציאים מהמאגר נתונים עוברים אוטומטית למשתנים מחרוזת של JSP.



MySQL 4.0 ומטה

בגרסאות MySQL 4 ומטה אין תמיכה ב- Unicode. זה מאוד בעייתי להשתמש ב- JAVA ובגרסה כזאתי של MySQL. מי שרוצה לעבוד עם MySQL בגרסאות ישנות, צריך לקודד את הנתונים שיוצאים מהמאגר נתונים ל- Unicode. לעוד מידע, ראה את המאמר על שימוש כללי ב- JDBC.



MySQL 4.1 והעתיד

עם הוצאתו של MySQL 4.1, החליטו כי MySQL יעבור להשתמש בקידוד Unicode כברירת מחדל. בגלל המעבר הזה, חלק מהמתכנתים שעובדים עם PHP (כמוני), שמים לב שבמקום עברית, יוצא סימני שאלה. אבל מה קורה עם JSP? מצויין. אין צורך להעביר קידודים, לשנות את הקידוד של עמודי ה- JSP וכדומה. MySQL 4.1 ו- JSP מתאימים בדיוק אחד לשני.



הגדרת MySQL להשתמש בקידוד Unicode

בעצם כל הנתונים נשמרים ב- Unicode ואי אפשר לשנות את זה. אבל צריך לוודא כי הגדרות השרת מתאימים לנו. MySQL יכול לשלוף נתונים בכל מיני קידודים, ואנחנו צריכים לראות את הוא עובד רק על Unicode.

בעזרת אשף ההגדרות החדש של MySQL, ניתן להגדיר בקלות את הקידוד של MySQL. מסך זה יופיע לאחר מספר מסכים. בחר את האפשרות השנייה (UTF-8). UTF-8 נקרא הקידוד עצמו. Unicode זה השיטה עצמה. לא ממש עקרוני לנו.






שימוש בקידוד UTF-8 בדפי JSP

טוב, עכשיו אנחנו משתמשים בקידוד אחר מאשר iso-8859-8 שהתרגלנו אליו. צריך גם לשנות את הדפים שישתמשו בקידוד הזה. פקודת %page צריכה להיות:






1
2
3  




<%@ page contentType="text/html; charset=utf-8" %>


עכשיו עמודי ה- JSP יהיו בקידוד UTF-8, כמו המאפיינים של העמוד הבא:






עורכי JSP

כשעובדים ב- Unicode, צריך לדאוג שגם התוכנות שלכם יידעו כי העמודים הם בקידוד אחר. בכל תוכנה יש בד"כ הגדרות קידוד. יש לבחור UTF-8. לדוגמא, פנקס הרשימות של Windows מאפשר לשמור קבצים בקידודים שונים:




אם מנסים לפתוח עמוד בקידוד Unicode בקידוד אחר, כל המידע שלא באנגלית לא יוצג כראוי. אם מנסים לשמור את המידע הזה, כל העברית תהפוך לסימני שאלה. משום כך, צריך לוודא פעמים כי התוכנות שלכם יודעות מה זה Unicode.



הערת עורך עדי לב

לפעמים מעדיפים לעבוד עם דף JSP בעברית ולהמיר את הנתונים לפני השמירה

לדוגמא: דף מוגדר בעברית

Jsp…
<%@ page
language=
"java"
contentType=
"text/html; charset=WINDOWS-1255"
pageEncoding=
"WINDOWS-1255"
%>

או
<%response.setContentType("text/html;charset=windows-1255");%>
<form name="form1" target="/servlet" action="get">
<input type="text" name="field1" id="field1">
</form>
והתוכנית המטפלת בטופס:

Servlet…
/*
הפונקציה ממירה מקוד עברית
Windows-1255
ל-
Unicode
*/
    public static final String toUnicode( String src ) {
        if (src == null){
            return "";
        }
        char chars[] = src.toCharArray();
        for ( int i = 0; i < chars.length; i++ ) {
            if ( chars[i] >= 224 && chars[i] <= 250 ) {
                chars[i] += ( 'א' – 224 );
            }
        }
        return new String( chars );
    }
 //
המרה לפני שמירה

protected void doGet(HttpServletRequest request, HttpServletresponse response){
    String unicodeField1=toUnicode(request.getParameter("Field1");
….




המאמר נכתב ע"י הדר פורת
Keynetik – בניית אתרים

תגיות: , , , , , ,

תגובות בפייסבוק