Vodič kroz ResourceBundle

1. Pregled

Mnogi programeri softvera, tijekom svoje profesionalne karijere, suočavaju se s mogućnošću razvoja višejezičnih sustava ili aplikacija. Obično su namijenjeni krajnjim korisnicima iz različitih regija ili različitih jezičnih područja.

Uvijek je izazov održavati i proširiti ove programe. Obično je presudna sposobnost istodobnog rada s različitim podacima o lokalizaciji. Izmjena podataka aplikacije trebala bi biti što jednostavnija bez potrebe za ponovnom kompilacijom. Zbog toga uglavnom izbjegavamo kodiranje naziva naljepnica ili gumba.

Srećom, možemo se oslanjati na Javu koja nam pruža ovu klasu koja nam pomaže u rješavanju svih gore spomenutih problema.

Jednostavno rečeno, ResourceBundle omogućuje našoj aplikaciji učitavanje podataka iz različitih datoteka koje sadrže podatke specifične za lokalno okruženje.

1.1. Paketi resursa

Prvo što bismo trebali znati je da su sve datoteke unutar jedan paket resursa mora biti u istom paketu / direktoriju i imati zajedničko osnovno ime. Mogu imati lokacijske specifične sufikse koji označavaju jezik, državu ili platformu odvojeni donjim znakom.

Važno je da možemo dodati pozivni broj države ako već postoji jezični kôd ili platformu ako postoje kodovi jezika i zemalja.

Pogledajmo primjere naziva datoteka:

  • ExampleResource
  • ExampleResource_en
  • ExampleResource_en_US
  • ExampleResource_en_US_UNIX

Zadana datoteka za svaki paket podataka uvijek je ona bez sufiksa - ExampleResource. Kao što postoje dvije podrazrede ResourceBundle: PropertyResourceBundle i ListResourceBundle, možemo naizmjenično čuvati podatke u datotekama svojstava, kao i u Java datotekama.

Svaka datoteka mora imati naziv specifičan za lokalno područje i odgovarajući nastavak datoteke, na primjer, ExampleResource_en_US.properties ili Example_en.java.

1.2. Datoteke svojstava - PropertyResourceBundle

Datoteke svojstava predstavljene su s PropertyResourceBundle. Podaci pohranjuju u obliku parova ključ / vrijednost osjetljivih na velika i mala slova.

Analizirajmo datoteku uzorka svojstava:

# Gumbi continueButton continue cancelButton = otkaži! Oznake helloLabel: zdravo 

Kao što vidimo, postoje tri različita stila definiranja parova ključ / vrijednost.

Svi su ekvivalentni, ali prvi je među njima vjerojatno najpopularniji Java programeri. Vrijedno je znati da komentare možemo stavljati i u datoteke svojstava. Komentari uvijek počinju s # ili !.

1.3. Java datoteke - ListResourceBundle

Prije svega, da bismo pohranili naše podatke specifične za jezik, moramo stvoriti klasu koja se proširuje ListResourceBundle i poništava getContents () metoda. Konvencija o nazivu klase ista je kao i za datoteke svojstava.

Za svakoga Lokalno, moramo stvoriti zasebnu Java klasu.

Evo primjera klase:

javna klasa ExampleResource_pl_PL proširuje ListResourceBundle {@Override zaštićeni objekt [] [] getContents () {return new Object [] [] {{"currency", "polish zloty"}, {"toUsdRate", new BigDecimal ("3.401")} , {"gradovi", novi niz [] {"Varšava", "Krakov"}}}; }}

Java datoteke imaju jednu glavnu prednost nad datotekama svojstava, a to je mogućnost držanja bilo kojeg predmeta koji želimo - ne samo Žice.

S druge strane, svaka izmjena ili uvođenje nove java klase specifične za lokalno područje zahtijeva rekompilaciju aplikacije dok se datoteke svojstava mogu proširiti bez ikakvih dodatnih napora.

2. Koristite svežnjeve resursa

Već znamo kako definirati snopove resursa, pa smo ih spremni koristiti.

Razmotrimo kratki isječak koda:

Lokalni jezik = novi lokalni jezik ("pl", "PL"); ResourceBundle exampleBundle = ResourceBundle.getBundle ("package.ExampleResource", lokalizacija); assertEquals (exampleBundle.getString ("valuta"), "poljski zlot"); assertEquals (exampleBundle.getObject ("toUsdRate"), novi BigDecimal ("3.401")); assertArrayEquals (exampleBundle.getStringArray ("gradovi"), novi String [] {"Varšava", "Krakov"});

Prvo, možemo definirati svoje Lokalno, osim ako ne želimo koristiti zadani.

Nakon toga nazovimo statičku tvorničku metodu ResourceBundle. Moramo proći naziv paketa sa paketom / direktorijom a lokalitet kao parametri.

Postoji i tvornička metoda koja zahtijeva naziv snopa samo ako je zadana lokalizacija u redu. Čim imamo objekt, možemo dohvatiti vrijednosti pomoću njihovih ključeva.

Uz to, primjer pokazuje da možemo koristiti getString (String ključ), getObject (String ključ), i getStringArray (String ključ) da bismo dobili vrijednosti koje želimo.

3. Odabir odgovarajućeg resursa snopa

Ako želimo koristiti paketni resurs, važno je znati kako Java odabire datoteke snopa.

Zamislimo da radimo s aplikacijom koja treba naljepnice na poljskom jeziku, ali vaše zadane JVM lokalitet je Lokale.US.

Na početku će aplikacija tražiti datoteke na putu predavanja koje odgovaraju lokalitetu koji tražite. Počinje najkonkretnijim nazivom, odnosno onim koji sadrži platformu, zemlju i jezik.

Zatim, ide na općenitije. Ako nema podudaranja, ovaj put se vraća na zadani jezik bez provjere platforme.

U slučaju nepodudaranja, pokušat će pročitati zadani paket. Sve bi trebalo biti jasno kad pogledamo redoslijed odabranih imena datoteka:

  • Oznaka_pl_PL_UNIX
  • Oznaka_pl_PL
  • Oznaka_pl
  • Oznaka_en_US
  • Oznaka_en
  • Označiti

Treba imati na umu da svako ime predstavlja oboje .Java i .Svojstva datoteke, ali prva ima prednost nad drugom. Kad nema odgovarajuće datoteke, a MissingResourceException baca se.

4. Nasljeđivanje

Još jedna prednost koncepta snopa resursa je nasljeđivanje imovine. To znači da parove ključ / vrijednost uključene u manje određene datoteke nasljeđuju oni koji su viši u stablu nasljeđivanja.

Pretpostavimo da imamo tri datoteke svojstava:

# resource.properties cancelButton = poništi # resource_pl.properties continueButton = dalej # resource_pl_PL.properties backButton = cofnij

Dohvaćen je paket resursa za Jezik ("pl", "PL") bi vratio sve tri ključa / vrijednosti u rezultatu. Vrijedno je spomenuti, nema povratka na zadani lokalni paket što se tiče nasljeđivanja imovine.

Što je više, ListResourceBundles i PropertyResourceBundles nisu u istoj hijerarhiji.

Dakle, ako se datoteka svojstava pronađe u putu predavanja, parovi ključ / vrijednost nasljeđuju se samo iz datoteka svojstava. Isto se pravilo odnosi na Java datoteke.

5. Prilagođavanje

Sve što smo gore naučili bilo je o zadanoj implementaciji ResourceBundle. Međutim, postoji način na koji možemo modificirati njegovo ponašanje.

To činimo proširivanjem ResourceBoundle.Control i nadjačavanje njegovih metoda.

Na primjer, možemo promijeniti vrijeme čuvanja vrijednosti u predmemoriji ili odrediti stanje kada se predmemorija treba ponovno učitati.

Za bolje razumijevanje, pripremimo kratku metodu kao primjer:

javna klasa ExampleControl proširuje ResourceBundle.Control {@Override javni popis getCandidateLocales (String s, Locale locale) {return Arrays.asList (new Locale ("pl", "PL")); }}

Svrha ove metode je promijeniti način odabira datoteka na putu predavanja. Kao što vidimo, ExampleControl vratit će samo poljski Lokalno, bez obzira što je zadano ili definirano Lokalno je.

6. UTF-8

Budući da još uvijek postoji mnogo aplikacija koje koriste JDK 8 ili starije verzije, vrijedi to znati prije Java 9ListResourceBundles imao još jednu prednost nad PropertyResourceBundles. Kako Java datoteke mogu pohraniti String objekte, one mogu sadržavati bilo koji znak koji podržava UTF-16 kodiranje.

Baš suprotno, PropertyResourceBundle učitava datoteke prema zadanim postavkama pomoću ISO 8859-1 kodiranje, koje ima manje znakova od UTF-8 (što stvara probleme našim primjerima poljskog jezika).

Kako bi se spasili znakovi koji su izvan UTF-8, možemo koristiti Native-to-ASCII pretvarač - domorodac2ascii. Kodiranjem pretvara sve znakove koji nisu u skladu s ISO 8859-1 \ uxxxx notacija.

Evo primjera naredbe:

native2ascii -kodiranje UTF-8 utf8.properties nonUtf8.properties

I pogledajmo kako izgledaju svojstva prije i nakon promjene kodiranja:

#Before polishHello = cześć #After polishHello = cze \ u015b \ u0107

Srećom, ova neugodnost više ne postoji u Javi 9. JVM čita datoteke svojstava u programu UTF-8 kodiranje i nema problema u korištenju nelatiničnih znakova.

7. Zaključak

BundleResource sadrži mnogo onoga što nam je potrebno za razvoj višejezične aplikacije. Značajke koje smo obradili čine manipulaciju različitim lokalitetima prilično jednostavnom.

Također izbjegavamo vrijednosti kodiranja, što nam omogućuje proširivanje podržanih Mjesta jednostavnim dodavanjem novog Lokalno datoteke koje omogućuju nesmetano mijenjanje i održavanje naše aplikacije.

Kao i uvijek, uzorak koda dostupan je na više od GitHub-a.