JSF locale issue
I have a situation where when a user selects a language from a drop down, I want the the application locale to 开发者_如何学Pythonchange accordingly. Capturing locale is not difficult, but how to set the locale for all pages there after.
I have configuration set in resource bundles and faces-config.xml
Registering your own ViewHandler
and overriding its calculateLocale() method would be one way to go.
Custom ViewHandler
needs to be indicated in faces-config.xml
file, e.g.:
<faces-config version="2.0" xmlns...>
<application>
...
<view-handler>your.package.CustomLocaleViewHandler</view-handler> ...
And the implementation would override the calculateLocale()
only and delegate other methods to proxied ViewHandler
:
public class CustomLocaleViewHandler extends ViewHandler {
private final ViewHandler base;
public CustomLocaleViewHandler(ViewHandler base) {
this.base = base;
}
@Override
public Locale calculateLocale(FacesContext context) {
//... your logic goes here
return locale;
}
@Override
public String calculateRenderKitId(FacesContext context) {
return base.calculateRenderKitId(context);
}
@Override
public UIViewRoot createView(FacesContext context, String viewId) {
return base.createView(context, viewId);
}
... other proxied methods
}
I believe this is what you are looking for:
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(locale);
I just went through this, and it's not difficult to code, but takes a bit to figure out how to do effectively in a future-proof and automated fashion, but I think I have a reasonable approach that automatically detects what languages are configured in JSF, and that localizes the menu items to the current Locale automatically.
First, make sure you're using a facelets template of some sort, or you're going to have to replicate this first part on every page you use. You set the Locale using the f:view locale= parameter
Your page(s) should look something like this:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:view locale="#{LocaleBean.currentLocale}">
<h:head>
...
</h:head>
<h:body>
...
<!-- Put this somewhere convenient on your page -->
<h:form>
<h:selectOneMenu value="#{Locale.currentLocale}" onchange="this.form.submit();" immediate="true" >
<f:selectItems value="#{Locale.supportedLocales}" var="loc" itemLabel="#{loc.getDisplayName(Locale.currentLocale)}" itemValue="#{loc}"/>
<f:converter converterId="LocaleConverter"/>
</h:selectOneMenu>
</h:form>
...
</h:body>
</f:view>
</html>
Here's my LocaleBean: (Register it with either @ManagedBean, or via faces-config.xml with a session scope)
public class LocaleBean {
protected List<Locale> supportedLocales = new ArrayList<Locale>();
protected Locale currentLocale;
/**
* Get the value of currentLocale
*
* @return the value of currentLocale
*/
public Locale getCurrentLocale() {
if (currentLocale == null && FacesContext.getCurrentInstance() != null) {
currentLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
}
return currentLocale;
}
/**
* Set the value of currentLocale
*
* @param currentLocale new value of currentLocale
*/
public void setCurrentLocale(Locale currentLocale) {
this.currentLocale = currentLocale;
FacesContext.getCurrentInstance().getViewRoot().setLocale(currentLocale);
}
public List<Locale> getSupportedLocales() {
if (supportedLocales.isEmpty() && FacesContext.getCurrentInstance() != null) {
Iterator<Locale> facesLocales = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
while (facesLocales.hasNext()) {
supportedLocales.add(facesLocales.next());
}
}
return supportedLocales;
}
public void setSupportedLocaleStrings(Collection<String> localeStrings) {
supportedLocales.clear();
for (String checkLocale : localeStrings) {
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.toString().equals(checkLocale)) {
supportedLocales.add(locale);
break;
}
}
}
}
}
And the LocaleConverter (again, register via annotations or faces-config.xml)
public class LocaleConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.toString().equals(value)) {
return locale;
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value.toString();
}
}
精彩评论