Internazionalizzazione con Java Server Faces
In questi giorni mi sto dando allo studio delle Java Server Faces (JSF) e mi sono subito imbattuto in un problema: l'internazionalizzazione.
Volendo evitare modalità "classiche" tipo cookie o salvare i testi direttamente dentro un classe, possiamo procedere in questo modo.
Nel mio package ho creato un sotto package con dentro i file di properties: com.mf.language.
I file di properties devono avere questa nomenclatura: nome_lingua.properties, tranne quello di default.
Io ne ho due:
- messages.properties (italiano)
- messages_en.properties (inglese)
I file di properties lavorano con il concetto di chiave:valore:
ciao=CIAO!
Poi dovete scrivere l'equivalente per la altre lingue nei file appositi.
A questo punto creiamo, se non esiste già, il file di configurazione faces-config.xml dentro a WEB-INF, con questo dentro:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<locale-config>
<default-locale>it</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
<resource-bundle>
<base-name>com_mf.language.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
In pratica gli diciamo dove sono i file delle lingue, e ne impostiamo una di default.
A questo punto creiamo un ManagedBean per gestire le lingue:
@ManagedBean(name = "language")
@SessionScoped
public class LanguageBean implements Serializable {private static final long serialVersionUID = 1L;
private String locale;
private static Map countries;static {
countries = new LinkedHashMap();
countries.put("Italiano", Locale.ITALIAN);
countries.put("English", Locale.ENGLISH);
}public Map getCountries() {
return countries;
}public String getLocale() {
return locale;
}public void setLocale(String locale) {
this.locale = locale;
}public void localeChanged(ValueChangeEvent e) {
String newLocaleValue = e.getNewValue().toString();
for (Map.Entry entry : countries.entrySet()) {
if (entry.getValue().toString().equals(newLocaleValue)) {
FacesContext.getCurrentInstance().getViewRoot().setLocale((Locale) entry.getValue());
}
}
}
}
Adesso non rimane altro che richiamare il tutto dentro una pagina web:
<h:form>
<h:outputText value="#{msg['ciao']}" /><br/>
<h:selectOneMenu value="#{language.locale}" onchange="submit()" valueChangeListener="#{language.localeChanged}">
<f:selectItems value="#{language.countries}"/>
</h:selectOneMenu>
</h:form>
Prima richiamiamo il valore ciao, e sotto riempiamo una lista con le lingue disponibili.
Quando si cambia valore della lista viene cambiata la lingua tramite il metodo localeChanged e aggiornata la pagina.
Sicuramente due miglioramenti da fare sono:
- salvare la lingua scelta in sessione o su database per ritrovarsela
- creare le voci della lista delle lingue disponibili su un file e non direttamente nel codice
In sostanza con queste due modifiche renderemmo il tutto un pò più flessibile e comodo.
Ciao!
java jsf java server faces managedbean internationalization properties faces-config web-inf
Commentami!