מדריך ל- ResourceBundle

1. סקירה כללית

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

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

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

במילים פשוטות, ה ResourceBundle מאפשר ליישום שלנו לטעון נתונים מקבצים נפרדים המכילים נתונים ספציפיים לאזור.

1.1. ResourceBundles

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

חשוב שנצרף קוד מדינה אם כבר יש קוד שפה, או פלטפורמה אם קיימים שפות ומדינות מדינה.

בואו נסתכל על שמות קבצים לדוגמא:

  • ExampleResource
  • ExampleResource_en
  • דוגמה Resource_en_US
  • דוגמה Resource_en_US_UNIX

קובץ ברירת המחדל של כל חבילת נתונים הוא תמיד אחד ללא סיומות - ExampleResource. כיוון שישנן שתי מחלקות משנה של ResourceBundle: PropertyResourceBundle ו ListResourceBundle, אנו יכולים לשמור נתונים להחלפה בקבצי נכסים וכן בקבצי Java.

כל קובץ חייב להכיל שם ספציפי למקום ותוסף קבצים תקין, לדוגמה, דוגמאות Resource_en_US.properties אוֹ דוגמא_en.java.

1.2. קבצי נכסים - PropertyResourceBundle

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

בואו ננתח קובץ מאפיין לדוגמה:

# לחצנים המשך לחצן המשך ביטול כפתור = ביטול! תוויות שלום תווית: שלום 

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

כולם שווים, אך הראשון הוא כנראה הפופולרי ביותר בקרב ג'אווה מתכנתים. כדאי לדעת שנוכל להכניס הערות גם לקבצי נכסים. הערות מתחילות תמיד עם # אוֹ !.

1.3. קבצי Java - ListResourceBundle

קודם כל, כדי לאחסן את הנתונים הספציפיים לשפה שלנו, עלינו ליצור מחלקה שמתרחבת ListResourceBundle ועוקף את getContents () שיטה. מוסכמת שם הכיתה זהה לקבצי נכסים.

לכל אחד אזור, עלינו ליצור מחלקה נפרדת של Java.

הנה מחלקה לדוגמא:

מחלקה ציבורית ExampleResource_pl_PL מרחיב את ListResourceBundle {@Override Object Object [] [] getContents () {return Object new [] [] {{"currency", "polish zloty"}, {"toUsdRate", BigDecimal חדש ("3.401")} , {"ערים", מחרוזת חדשה [] {"ורשה", "קרקוב"}}}; }}

לקבצי Java יש יתרון אחד מרכזי על פני קבצי נכסים שהוא אפשרות להחזיק כל אובייקט שאנחנו רוצים - לא רק מיתרים.

מצד שני, כל שינוי או הקדמה של מחלקת Java חדשה ספציפית למיקום דורשת קומפילציה מחדש של יישום ואילו ניתן להרחיב את קבצי המאפיינים ללא כל מאמץ נוסף.

2. השתמש בחבילות משאבים

אנחנו כבר יודעים להגדיר חבילות משאבים, ולכן אנו מוכנים להשתמש בו.

בואו ניקח בחשבון את קטע הקוד הקצר:

אזור מקומי = אזור חדש ("pl", "PL"); ResourceBundle exampleBundle = ResourceBundle.getBundle ("package.ExampleResource", אזור); assertEquals (exampleBundle.getString ("מטבע"), "זלוטי פולני"); assertEquals (exampleBundle.getObject ("toUsdRate"), BigDecimal חדש ("3.401")); assertArrayEquals (exampleBundle.getStringArray ("ערים"), מחרוזת חדשה [] {"ורשה", "קרקוב"});

ראשית, אנו יכולים להגדיר את שלנו אזוראלא אם כן איננו רוצים להשתמש ברירת המחדל.

לאחר מכן, בואו נקרא לשיטת מפעל סטטית של ResourceBundle. אנחנו צריכים לעבור את שם הצרור עם החבילה / הספריה שלו והמקום כפרמטרים.

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

בנוסף, הדוגמה מראה שאנחנו יכולים להשתמש בה getString (מפתח מחרוזת), getObject (מפתח מחרוזת), ו getStringArray (מפתח מחרוזת) להשיג ערכים שאנחנו רוצים.

3. בחירת משאב הצרור המתאים

אם אנו רוצים להשתמש במשאב חבילות, חשוב לדעת כיצד ג'אווה בוחר קבצי חבילה.

בואו נדמיין שאנחנו עובדים עם יישום שזקוק לתוויות בפולנית אך ברירת המחדל שלכם JVM המקום הוא אזור .US.

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

ואז זה עובר לכללי יותר. אם אין התאמה, היא תחזור לאזור ברירת המחדל ללא בדיקת פלטפורמה הפעם.

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

  • Label_pl_PL_UNIX
  • Label_pl_PL
  • Label_pl
  • Label_en_US
  • Label_en
  • תווית

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

4. ירושה

יתרון נוסף במושג צרור המשאבים הוא ירושת רכוש. המשמעות היא שזוגות ערכי מפתח שנכללים בקבצים פחות ספציפיים עוברים בתורשה לאלה שנמצאים גבוה יותר בעץ הירושה.

נניח שיש לנו שלושה קבצי נכסים:

# resource.properties cancelButton = בטל # resource_pl.properties continueButton = dalej # resource_pl_PL.properties backButton = cofnij

חבילת המשאבים שאוחזרה עבור אזור ("pl", "PL") יחזיר את כל שלושת המקשים / הערכים בתוצאה. כדאי להזכיר, אין אפשרות לחזור לחבילה המקומית המוגדרת כברירת מחדל ככל שנחשבת לירושת רכוש.

מה עוד, ListResourceBundles ו PropertyResourceBundles אינם באותה היררכיה.

כך שאם נמצא קובץ מאפיין בנתיב הכיתה אז צמדי ערך המפתח עוברים בירושה רק מקבצי מאפיינים. אותו כלל חל על קבצי Java.

5. התאמה אישית

כל מה שלמדנו לעיל היה על יישום ברירת המחדל של ResourceBundle. עם זאת, יש דרך שנוכל לשנות את התנהגותה.

אנו עושים זאת על ידי הרחבה ResourceBoundle.Control ועוקף את שיטותיו.

לדוגמא, אנו יכולים לשנות את זמן שמירת הערכים במטמון או לקבוע את המצב בו יש לטעון מחדש את המטמון.

להבנה טובה יותר, בואו נכין שיטה קצרה כדוגמה:

מחלקה ציבורית ExampleControl מרחיבה את ResourceBundle.Control {@Override public List getCandidateLocales (String s, Locale locale) {return Arrays.asList (Local new ("pl", "PL")); }}

מטרת שיטה זו היא לשנות אופן בחירת קבצים בנתיב הכיתה. כמו שאנו יכולים לראות, דוגמה בקרה יחזיר רק פולנית אזורלא משנה מה ברירת המחדל או שהוגדרה אזור הוא.

6. UTF-8

מכיוון שעדיין יש יישומים רבים המשתמשים בהם JDK 8 או גרסאות ישנות יותר, כדאי לדעת זאת קודם ל ג'אווה 9ListResourceBundles היה יתרון אחד נוסף על PropertyResourceBundles. מכיוון שקבצי Java יכולים לאחסן אובייקטים מחרוזת, הם מסוגלים להחזיק כל תו הנתמך על ידי UTF-16 הַצפָּנָה.

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

על מנת לשמור תווים שהם מעבר UTF-8, אנחנו יכולים להשתמש ב- ילידי ASCII ממיר - native2ascii. הוא ממיר את כל התווים שאינם תואמים את ISO 8859-1 על ידי קידוד אליהם \ uxxxx סִמוּן.

הנה דוגמה לפקודה:

native2ascii-קידוד UTF-8 utf8.properties nonUtf8.properties

ובואו נראה איך נראים מאפיינים לפני ואחרי שינוי קידוד:

# לפני polishHello = cześć # לאחר polishHello = cze \ u015b \ u0107

למרבה המזל, אי הנוחות הזו כבר לא קיימת בג'אווה 9. JVM קורא קבצי נכסים ב UTF-8 קידוד, ואין שום בעיה להשתמש בתווים שאינם לטיניים.

7. מסקנה

BundleResource מכיל הרבה ממה שאנחנו צריכים כדי לפתח יישום רב לשוני. התכונות שסקרנו הופכות את המניפולציה של האזורים השונים לפשוטה למדי.

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

כמו תמיד, קוד הדוגמה זמין ב- GitHub.