views:

380

answers:

2

I'm new to JSF and I would like to internationalize my web page so the web site visitor would be able to switch between languages by clicking on flag icons representing each locale. I have edited my faces-config.xml and added resource bundle, default locale, and supported locales. Then I wrote a bean called changeLang.java which is supposed to be for doing the background job. When the page is evaulated I get the following error:

index.xhtml @8,89 locale="#{changeLang.currentLocale}" Attribute did not evaluate to a String or Locale: null

Technologies:
JSF 2.0 Mojarra 2.0.2
Spring 3.0.0
Facelets

My
changeLang.java file



package gui;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import javax.annotation.ManagedBean;
import javax.faces.context.FacesContext;
import org.springframework.context.annotation.Scope;

@ManagedBean
@Scope("session")

public class ChangeLang {
    private Locale currentLocale;

    public ChangeLang() {
           this.currentLocale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
    }
    public Locale getCurrentLocale() {
        return this.currentLocale;
    }
    public ArrayList getSupportedLocales(){
        ArrayList listOfSupp = new ArrayList();
        Iterator locales = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
        while(locales.hasNext()) {
            Locale locale = locales.next();
            listOfSupp.add(locale);
        }

    return listOfSupp;
    }
    public void setCurrentLocaleLanguage(String language) {
        FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(language));
    }
}

and "using page" snippet

 
f:view locale="#{changeLang.currentLocale}" contentType="text/html; charset=utf-8"

Full log:


An Error Occurred:
/index.xhtml @8,89 locale="#{changeLang.currentLocale}" Attribute did not evaluate to a String or Locale: null
- Stack Trace
javax.faces.view.facelets.TagAttributeException: /index.xhtml @8,89 locale="#{changeLang.currentLocale}" Attribute did not evaluate to a String or Locale: null
    at com.sun.faces.facelets.tag.jsf.ComponentSupport.getLocale(ComponentSupport.java:218)
    at com.sun.faces.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:119)
    at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:160)
    at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:86)
    at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:75)
    at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:145)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:716)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:619)
- Component Tree

- Scoped Variables
Request ParametersName  Value
None

View AttributesName Value
None

Request AttributesName  Value
None

Flash AttributesName    Value
None

Session AttributesName  Value
None

Application AttributesName  Value
csfcff  com.sun.faces.context.flash.ELFlash@119f705d

Please, would you be so kind and help me to solve this problem ?

Thanks for any advice.

  <locale-config>
        <default-locale>en</default-locale>
        <supported-locale>en</supported-locale>
        <supported-locale>sk</supported-locale>
        <supported-locale>ko</supported-locale>
    </locale-config>
A: 

Well, you need to set the default value. Either

Locale currentLocale = FacesContext.getCurrentContext()
           .getApplication().getDefaultLocale();

or

@PostConstruct
public void init() {
    currentLocale = FacesContext.getCurrentContext()
           .getApplication().getDefaultLocale();
}
Bozho
He already did it in the constructor. The problem is that the constructor doesn't look like a constructor due to the poor naming conventions. The other problem is that it returns the server side locale which may return null if not explicitly set/configured.
BalusC
ah, right.. well, he said he has set the default locale in faces-config.. but let's see it.
Bozho
A: 

The error says that the Locale is null while it may not be null. You need to preinitialize it with ExternalContext#getRequestLocale() which will return the client side locale, not with the Application#getDefaultLocale() which would return the server side locale which may be null if not explicitly configured.

So, update your code with

public changeLang() {
    this.currentLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}

That said, it's recommend to adhere the Sun Java Naming Conventions. Classnames ought to start with uppercase, else it would confuse everyone because it look like methods. Rename changeLang to ChangeLang.

BalusC
Well , I uppercased the first letter of the class name, then changed the constructor but I still get the same error.
init