开发者

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();
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜