Internationalisering/lokalisering p˚a webben

KTH
NADA
Språkteknologi
2D1418
Internationalisering/lokalisering på webben
Benny Ferander, 711119-0455
[email protected]
Stefan Westlund, 681206-0157
[email protected]
Sammanfattning
Idag läggs en allt större vikt på internationalisering och lokalisering vid
utveckling av programvara. Detsamma gäller för applikationer konstruerade
för webben. Det är viktigt att nå en alltmer internationell marknad.
Med hjälp av internationalisering och lokalisering skapas ett flexibelt
designmönster där komponenter kan adderas utan ingrepp i källkod. Det
låter komplicerat men är inte svårt att implementera.
Innehåll
1 Syfte
3
2 Metod
3
3 Grundläggande begrepp
3.1 Internationalisering . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Lokalisering . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
4
4 Två olika exempel i Java
4
5 Klassen Locale
5
6 Klassen ResourceBundle
6.1 .properties-filer . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
7 Internationalisering/Lokalisering på webben
7.1 Webbserver . . . . . . . . . . . . . . . . . . .
7.2 Java Servlets . . . . . . . . . . . . . . . . . .
7.3 PageBeans och JSP . . . . . . . . . . . . . . .
7.4 Möjlig tillämpning . . . . . . . . . . . . . . .
8
8
8
8
9
8 Slutsatser
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
2
1
Syfte
Vi fick i uppdrag att skriva en rapport om internationalisering och lokalisering i kursen Språkteknologi. Syftet med denna rapport är att klargöra
vad detta innebär. Vi kommer också att visa hur detta kan användas i en
webbapplikation.
2
Metod
Vi har läst igenom kursens material angående internationalisering och lokalisering. För att kunna realisera projektet har vi ingående studerat Javas
API. Våra egna erfarenheter från webbserverprogrammering har också kommit väl till pass.
Vi började med att skriva några enkla program i Java för att påvisa skillnaden mellan en internationaliserad och en icke internationaliserad applikation. Sedan skissade vi på en mer avancerad modell designad för webbändamål.
3
Grundläggande begrepp
3.1
Internationalisering
Internationalisering innebär att applikationer designas på ett sådant sätt
att de kan anpassas till varierande språk, region och kultur. Detta utan
att ändringar i källkod behövs göras. I en internationaliserad applikation är
källkod och lokalberoende data separerat.
Internationalisering kallas ofta för i18n, på grund av att det på engelska
heter internationalization, där det är 18 bokstäver mellan det första i:et och
det sista n:et.
En internationaliserad applikation har följande egenskaper:
• Om lokaliserat data adderas, ska samma applikation kunna köras i
hela världen.
• Textelement, som statusmeddelanden och komponenter i ett GUI är
inte hårdkodade. Istället lagras de utanför källkoden och återfås dynamiskt.
• Tillägg av nya språk kräver inte omkompilering.
• Kulturberoende data, som datum och valuta, återges på det format
som användaren är van vid i sin region och i sitt språk.
• Det är lätt att lägga till nya regioner och språk.
3
3.2
Lokalisering
Lokalisering innebär att mjukvara anpassas till en specifik region eller ett
specifikt språk. Detta görs genom att addera lokalspecifika komponenter,
bland annat texter översatta till olika språk.
Lokalisering kallas ibland l10n av samma skäl som internationalisering
kallas i18n.
4
Två olika exempel i Java
Följande kod kan endast presentera utdata på svenska:
public class InteInternationaliserat
{
public static void main(String[] args)
{
System.out.println("Hej.");
System.out.println("Hur mår du?");
System.out.println("Hejdå.");
}
}
Antag att vi nu vill att programmet ska visa olika meddelanden beroende
på om det är en engelsman eller en tysk som använder programmet. Meddelandena bör då flyttas ut från källkoden och in i textfiler som översättare
kan editera. Programmet behöver internationaliseras.
En internationaliserad version av programmet skulle se ut ungefär som
följer:
import java.util.*;
public class Internationaliserat
{
public static void main(String[] args)
{
String language;
String country;
if (args.length != 2){
language = new String("sv");
country = new String("SE");
}
else{
language = new String(args[0]);
country = new String(args[1]);
4
}
Locale currentLocale;
ResourceBundle messages;
currentLocale = new Locale(language, country);
messages = ResourceBundle.getBundle("MessagesBundle",
currentLocale);
System.out.println(messages.getString("greetings"));
System.out.println(messages.getString("inquiry"));
System.out.println(messages.getString("farewell"));
}
}
Om programmet skulle köras av exempelvis en engelsman skulle körningen
få följande utseende:
> java Internationaliserat en UK
Hello.
How are you?
Goodbye.
Om en tysk körde programmet skulle körningen se ut så här:
> java Internationaliserat de DE
Hallo.
Wie geht’s?
Tschüs.
Okej. Nu har vi ett program som är internationaliserat. Det återstår dock
att förklara koden ovan.
5
Klassen Locale
En instans av klassen Locale representerar en specifik grafisk, politisk eller
kulturell region. I Java skapar du en Locale genom att använda en av de två
konstruktörerna:
Locale(String language, String country)
Locale(String language, String country, String variant)
Det första argumentet till båda konstruktorerna är språkkoden enligt ISO639. Dessa hittas på webbadressen:
http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
5
Det andra argumentet till de båda konstruktörerna är landskoden enligt
ISO-3166. Dessa hittas på webbadressen
http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
Den andra konstruktören kräver ytterligare ett argument: variant. Denna
tänker vi inte presentera ytterligare utan hänvisar till Javas API.
Då man en gång instansierat ett Locale-objekt kan man få information
från den. Många av de klasser som används i Java för internationalisering
och lokalisering använder sig av Locale.
6
Klassen ResourceBundle
En instans av klassen ResourceBundle innehåller lokalspecifika objekt. Om
ditt program behöver lokalspecifika objekt, till exempel av typen String, så
kan programmet hämta det från en ResourceBundle som passar den tillfällige
användarens lokalitet. Detta hjälper dig att skriva program som:
• är lätt lokaliserade eller översatta till olika språk
• hanterar multipla lokaliteter samtidigt
• lätt kan modifieras
I det tidigare exemplet använde vi en ResourceBundle:
ResourceBundle messages;
...
messages = ResourceBundle.getBundle("MessagesBundle",
currentLocale);
Argumentet MessagesBundle är prefix på en fil med suffixet .properties.
Dessa förklaras mer nedan. Det som görs i ovanstående kod är helt enkelt
att det skapas en ResourceBundle som arbetar med en fil som har suffixet
.properties. Prefix på denna fil bestäms av aktuell locale och namnet MessagesBundle.
6.1
.properties-filer
Ovan nämnda .properties-filer behöver förklaras utförligt. Det är i dessa filer
de olika textmeddelandena skrivs in. Deras namn ska vara på en viss form:
baseclass + "_" + language + "_" + country + "_" + ".properties"
baseclass + "_" + language + ".properties"
baseclass + ".properties"
6
För att förklara detta lite bättre kan vi tänkas att vi vill kunna hantera två
språk i vårt program, till exempel svenska och engelska. Antag vidare att
vi vill att svenska ska vara det språk som används som default. “Baseclass”
skulle t.ex. kunna vara “textfil”. Då skulle vi ha följande två filer:
textfil.properties
textfil_en_UK.properties
Om användaren nu anger att han är engelsman kan han få text presenterad
från filen textfil_en_UK.properties. Om inget anges hämtas text från
filen textfil.properties.
I vår exempelkod har vi följande rader av kod:
System.out.println(messages.getString("greetings"));
System.out.println(messages.getString("inquiry"));
System.out.println(messages.getString("farewell"));
Det som händer här är att programmet först hämtar en textsträng från
vald propertyfil genom att ange nyckeln greetings och sedan skriver ut
den hämtade textsträngen på standard output. Sedan görs samma sak för
de andra nycklarna.
I vårt exempel ville vi att en engelsman, en tysk och en svensk skulle
kunna använda programmet på sitt eget språk. Om vi låter svenska vara
default behövs följande filer:
MessagesBundle.properties
MessagesBundle_en_UK.properties
MessagesBundle_de_DE.properties
Filen MessagesBundle.properties skulle se ut så här:
greetings = Hej
inquiry = Hur mår du?
farewell = Hejdå.
Filen MessagesBundle_en_UK.properties skulle se ut så här:
greetings = Hello
inquiry = How are you?
farewell = Goodbye.
och filen MessagesBundle_de_DE.properties skulle se ut så här
greetings = Hallo
inquiry = Wie geht’s?
farewell = Tschüs.
7
7
Internationalisering/Lokalisering på webben
Nu har vi visat grunderna i hur applikationer kan internationaliseras. En bra
tillämpning för detta är webben. Det är lätt att förstå att till exempel en
webbplats som syftar till att sälja en produkt på en internationell marknad
har ett starkt behov av internationalisering.
7.1
Webbserver
En bra lösning då man jobbar med Java och webbapplikationer är att
använda sig av den så kallade MVC-modellen1 . Med hjälp av en webbserver
som hanterar Java kan man bland annat använda sig av en kombination
av JSP2 och Java Servlets. Tomcat är en populär webbserver som uppfyller
dessa krav. Den kan hämtas från följande URL:
http://jakarta.apache.org/site/sourceindex.html
7.2
Java Servlets
En Java Servlet är en server-side-komponent skriven i Java och är tillhandahållen av en webbserver. En servlet instansieras av ett anrop från en browser. Denna servlet sköter logiken, och instansierar i sin tur en s.k. PageBean,
vilken utgör modellen i systemet.
7.3
PageBeans och JSP
PageBeans är enkla javaklasser som endast bör ha metoder av typen set och
get. Dessa instansieras av till exempel en servlet, som skickar med bönan
i anropet till JSP-sidan. Bönan innehåller information från exempelvis en
databas.
Viktigt att poängtera är att bönorna inte ska kunna kasta Exceptions
eftersom hantering av detta skulle kräva Javakod i JSP-sidan. Så skulle vara
fallet om vi skickade med hela ResourceBundle-objektet i anropet istället för
denna PageBean. Detta eftersom ResourceBundle kastar ett otal Exceptions
som måste hanteras på något sätt.
JSP är en sorts utökning av HTML, där det går att inkludera Java.
Men man bör undvika att skriva Javakod direkt i en JSP-sida. Tanken med
separeration mellan JSP och Java Servlets är att Java- och HTML-utvecklare
ska kunna jobba parallellt med olika uppdrag inom samma projekt. En av
de grundläggande orsakerna är att det inte går att använda sig av Javadoc3
i JSP.
1
Designmönstret Model-View-Controller
JavaServer Pages
3
Javas standardiserade dokumentationsverktyg
2
8
I JSP-sidan går det att addera egna taggar, vilket till exempel möjliggör
iteration genom en objektvektor. Bönans get-metoder används av JSP-sidan
till att visa specifik information.
JSP-sidan kompileras av webbservern till en servlet. Detta är dock ingenting som utvecklaren behöver tänka på.
7.4
Möjlig tillämpning
Då en användare ansluter till systemet finns tre möjligheter till lokalisering.
Det ena är att användaren varje gång väljer språk genom att till exempel
klicka på en flagga. Den andra möjligheten är att uppgifter om språkval
lagras i användarens dator i form av en cookie4 . Den tredje möjligheten är
att uppgifter om användarens språk sparas i en databas och hämtas vid
inloggningen.
Att välja språk varje gång är den enklaste lösningen, men kan vara enerverande för användaren om han frekvent återkommer till sidan. Att använda
cookies är bra så länge användarens browser accepterar dem. Men cookies
har nackdelen att de lagras lokalt, vilket inte fungerar om användaren byter dator. Den lösning som förefaller mest professionell är att uppgifterna
lagras i en databas kopplad mot webbservern. Då spelar det ingen roll om
användaren har bytt dator. Dessutom kan han ändra inställningar i efterhand om utvecklaren implementerar detta. En användarprofil är skapad. Till
användarnamnet hör nu lokalisering.
Så här designar vi modellen; Ett anrop till en webbserver passerar en
kontroller, vilken skickar anropet till rätt Java Servlet. Servleten tar hand
om anropet och exekverar nödvändig kod utifrån information i anropets
header. Denna kod skulle till exempel kunna genomföra en säkerhetskontroll
och helt sonika vägra utföra anrop från en icke inloggad användare. Logiken
instansierar en eller flera PageBeans som skickas med till JSP-sidan. En av
dessa PageBeans skulle kunna innehålla språkinformationen.
4
En cookie är en beständig informationsteckensträng som browsern skickar med vid
anropet
9
Vår JSP-sida använder sig av dessa PageBeans. Språkinformationen liksom användarinformationen i bönorna används i sidan med hjälp av getmetoderna. Hela webbapplikationen har nu blivit internationaliserad.
10
8
Slutsatser
Användningen av internationalisering och lokalisering kommer att öka markant. Detta grundar vi på att elektronisk handel ökat på Internet. Dessutom
har marknaden blivit alltmer internationell. Det finns mycket pengar att
tjäna genom internationalisering och lokalisering av webbapplikationer.
11
Referenser
[1] The Java Tutorial
http://java.sun.com/docs/books/tutorial/i18n/index.html
[2] Allaramaju, Subrahmanyam Professional Java Server Programming
J2EE: 1.3 Edition
12