Question

I am using SEAM 2's LocaleSelector to set the locale in my application which works ok

I am also using JAWR's i18n message generator to make the messages available as a Javascript variable, as per the instructions here I have created a class that resolves the current locale so that JAWR loads the correct message bundle, here is my code

@Name("localeResolver")
public class LocaleResolver implements net.jawr.web.resource.bundle.locale.LocaleResolver {

    @In private LocaleSelector localeSelector;

    public LocaleResolver() {}

    @Override
    public String resolveLocaleCode(HttpServletRequest request) {
        if(localeSelector!=null){
            System.out.println("locale selector is not null setting jawr locale to "+localeSelector.getLocaleString());
            return localeSelector.getLocaleString();
        }else{
            System.out.println("locale selector is null setting jawr locale to "+request.getLocale().toString());
            return request.getLocale().toString();
        }   
    }
}

But localeSelector is always null, so it is setting using request.getLocale, which seems to be the browsers default locale (no good if the user wishes to manually override)

Why would the injected localeSelector be null, I have sucessfully injected it in other components?

Thanks

Update: web.xml contents

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <context-param>
  <param-name>facelets.DEVELOPMENT</param-name>
  <param-value>true</param-value>
 </context-param>
 <context-param>
  <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
  <param-value>.xhtml</param-value>
 </context-param>
 <context-param>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>server</param-value>
 </context-param>
 <context-param>
  <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
  <param-value>com.sun.facelets.FaceletViewHandler</param-value>
 </context-param>
 <context-param>
  <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
  <param-value>Mojarra-1.2</param-value>
 </context-param>
 <context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>plain</param-value>
 </context-param>
 <!-- Richfaces Global Ajax Que,
     added as getting concurrent conversation access exceptions
     from unknown locations -->
 <context-param>
  <param-name>org.richfaces.queue.global.enabled</param-name>
  <param-value>true</param-value>
 </context-param>

 <filter>
  <filter-name>Seam Filter</filter-name>
  <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
 </filter>

 <!-- Seam -->
 <listener>
  <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
 </listener>
 <servlet>
  <servlet-name>Seam Resource Servlet</servlet-name>
  <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
 </servlet>
 <!-- JSF -->
 <servlet>
  <servlet-name>Document Store Servlet</servlet-name>
  <servlet-class>org.jboss.seam.document.DocumentStoreServlet</servlet-class>
 </servlet>
 <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <!-- jawr Servlet -->

 <servlet>
    <servlet-name>JavascriptServlet</servlet-name>
    <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class>

    <!-- Location in classpath of the config file -->
    <init-param>
        <param-name>configLocation</param-name>
        <param-value>/jawr.properties</param-value>
    </init-param>
    <init-param>
        <param-name>mapping</param-name>
        <param-value>/jsJawrPath/</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>JavascriptServlet</servlet-name>
    <url-pattern>/jsJawrPath/*</url-pattern>
</servlet-mapping>


 <!-- Store item Servlet -->
 <servlet-mapping>
  <servlet-name>Document Store Servlet</servlet-name>
  <url-pattern>*.csv</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>Document Store Servlet</servlet-name>
  <url-pattern>*.xls</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>Document Store Servlet</servlet-name>
  <url-pattern>*.pdf</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.xhtml</url-pattern>
 </servlet-mapping>
 <!-- 120 min session timeout -->
 <session-config>
  <session-timeout>120</session-timeout>
 </session-config>
 <!-- Mime types -->
 <mime-mapping>
  <extension>htc</extension>
  <mime-type>text/x-component</mime-type>
 </mime-mapping>
 <!-- Index file def -->
 <welcome-file-list>
  <welcome-file>index.xhtml</welcome-file>
 </welcome-file-list>
 <!-- Server error page -->
 <error-page>
  <error-code>500</error-code>
  <location>/error.xhtml</location>
 </error-page>
 <!-- File not found page -->
 <error-page>
  <error-code>404</error-code>
  <location>/resourceNotFound.xhtml</location>
 </error-page>
 <!-- Unathorised pages -->
 <error-page>
  <error-code>401</error-code>
  <location>/notAuthorised.xhtml</location>
 </error-page>
 <error-page>
  <error-code>403</error-code>
  <location>/index.xhtml</location>
 </error-page>
</web-app>
Was it helpful?

Solution 2

Ok I solved this by manually looking up the component rather than injection using the following

public class LocaleResolver implements net.jawr.web.resource.bundle.locale.LocaleResolver {

    public LocaleResolver() {}

    public String resolveLocaleCode(HttpServletRequest request) {
        //Lookup component manually as not part of SEAM lifecycle
        LocaleSelector localeSelector = (LocaleSelector)Contexts.getSessionContext().get(LocaleSelector.class);
        if(localeSelector!=null){
            return localeSelector.getLocaleString();
        }else{
            return request.getLocale().toString();
        }   
    }
}

I believe this is because the implemented LocaleResolver is not part of the seam lifecycle and therefore is not intercepted, but I could be wrong...?

OTHER TIPS

Your LocaleResolver is being called as part of a separate Servlet request that is not routed through the standard JSF Servlet. When this happens, Seam interceptors are not triggered and bijection does not take place.

To solve the problem, you need to notify Seam about the incoming request so that it sets up its contexts properly (note that you need to close the lifecycle so returning the obtained value will not do):

ServletLifecycle.beginRequest(request);
String locale = LocaleSelector.instance().getLocaleString();
ServletLifecycle.endRequest();
return locale;

Alternatively, you can use the provided ContextualHttpServletRequest class, which does the same thing in a cleaner way (closing the lifecycle in a finally block, etc.):

final String[] locale = new String[1];
new ContextualHttpServletRequest(request) {
    @Override
    public void process() throws ServletException, IOException {
        // Do the things that need to access Seam contexts within this function:
        locale[0] = LocaleSelector.instance().getLocaleString();
    }
}.run();
return locale[0];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top