我正在尝试在JSF 2中实现国际化。我尝试了很多解决方案,但是我无法让它改变视图语言环境。这是faces-config.xml
文件的代码:
<application>
<locale-config>
<default-locale>es</default-locale>
<supported-locale>en_GB</supported-locale>
<supported-locale>fr</supported-locale>
</locale-config>
<resource-bundle>
<base-name>malagaAcoge.configuracion.Messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
我正在使用位于我的源包中的3个属性。
这是我的观点:
<f:view locale="#{idiomaBean.locale}">
<div id="contenedor">
<div id="cabecera"
style="background: url('../images/logo/fondoCabecera.png') no-repeat">
</div>
<div id="cuerpo">
<div id="center">
<h:form prependId="false" id="form_login">
<h:selectOneMenu value="#{idiomaBean.locale}"
onchange="submit()"
valueChangeListener="#{idiomaBean.changeLanguage}">
<f:selectItems value="#{idiomaBean.countriesInMap}" />
</h:selectOneMenu>
<h:panelGrid columns="3">
<p:commandLink title="SP" action="#{idiomaBean.changeLanguage}">
<p:graphicImage value="../images/paises/sp.png"></p:graphicImage>
</p:commandLink>
<p:commandLink title="EN" action="#{idiomaBean.changeLanguage}">
<p:graphicImage value="../images/paises/en.png">
</p:graphicImage>
</p:commandLink>
<p:commandLink title="FR" action="#{idiomaBean.changeLanguage}">
<p:graphicImage value="../images/paises/fr.png">
</p:graphicImage>
<f:setPropertyActionListener target="#{idiomaBean.locale}"
value="fr"></f:setPropertyActionListener>
</p:commandLink>
</h:panelGrid>
这是我用来执行更改的IdiomaBean
:
private static final long serialVersionUID = 1L;
private static String locale = FacesContext.getCurrentInstance()
.getViewRoot().getLocale().getLanguage();
private static Map<String, Object> countries;
static {
countries = new LinkedHashMap<String, Object>();
countries.put("Español", new Locale("es")); // label, value
countries.put("English", Locale.ENGLISH);
countries.put("Français", Locale.FRENCH);
}
public Map<String, Object> getCountriesInMap() {
return countries;
}
public String getLocale() {
return locale;
}
@SuppressWarnings("static-access")
public void setLocale(String locale) {
this.locale = locale;
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(locale));
}
public void changeLanguage(ValueChangeEvent e) {
String newLocaleValue = e.getNewValue().toString();
// loop country map to compare the locale code
for (Map.Entry<String, Object> entry : countries.entrySet()) {
if (entry.getValue().toString().equals(newLocaleValue)) {
FacesContext.getCurrentInstance().getViewRoot()
.setLocale((Locale) entry.getValue());
}
}
我在Tomcat服务器上使用PrimeFaces 3.0。
答案 0 :(得分:4)
您的问题描述中并不清楚。该下拉列表看起来像它将起作用(尽管值更改侦听器完全是多余的),但这些链接确实根本不起作用。我假设您实际上正在询问如何正确实现链接。
首先,在下拉列表和图像链接中删除值更改侦听器方法。您对旧值不感兴趣,您只对新值感兴趣,因此您根本不需要它。当你使用PrimeFaces 3.0时,它又需要Servlet 3.0,后者又与EL 2.2一起出现,你应该能够在EL中传递方法参数。您只需要将Locale
参数更改为String
类型,以便它也可以用作链接方法参数。
此外,您绝对不应该使用户选择的区域设置static
。它将在同一个应用程序中的所有用户之间共享。因此,如果一个用户更改了区域设置,那么每个其他访问者都会看到最后一个用户选择的区域设置!使它成为会话范围bean的非静态属性。
所以,这应该做
<f:view locale="#{idiomaBean.locale}">
<h:form>
<h:selectOneMenu value="#{idiomaBean.language}" onchange="submit()">
<f:selectItems value="#{idiomaBean.availableLanguages}" />
</h:selectOneMenu>
<h:panelGrid columns="3">
<p:commandLink title="SP" action="#{idiomaBean.setLanguage('sp')}" update="@all">
<p:graphicImage value="../images/paises/sp.png" />
</p:commandLink>
<p:commandLink title="EN" action="#{idiomaBean.setLanguage('en')}" update="@all">
<p:graphicImage value="../images/paises/en.png" />
</p:commandLink>
<p:commandLink title="FR" action="#{idiomaBean.setLanguage('fr')}" update="@all">
<p:graphicImage value="../images/paises/fr.png" />
</p:commandLink>
</h:panelGrid>
</h:form>
</f:view>
与
@ManagedBean
@SessionScoped
public class IdiomaBean implements Serializable {
private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
private static Map<String, String> availableLanguages;
static {
availableLanguages = new LinkedHashMap<String, String>();
availableLanguages.put("Español", "es");
availableLanguages.put("English", "en");
availableLanguages.put("Français", "fr");
}
public Map<String, String> getAvailableLanguages() {
return availableLanguages;
}
public Locale getLocale() {
return locale;
}
public String getLanguage() {
return locale.getLanguage();
}
public void setLanguage(String language) {
locale = new Locale(language);
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
}
}