Question

I want to set the JSTL locale which is used by <fmt:formatNumber> and friends. I know this is possible with <fmt:setLocale>, but I need to do it dynamically (depending on user data retrieved from my DB) and would prefer Java code - a filter class, to be precise.

I thought setting the session attribute javax.servlet.jsp.jstl.fmt.locale to my desired Locale instance would do the trick, but it is ignored: The JSTL tags keep using the browser locale.

I verified there are no page context or request attributes of the same name.

So what am I doing wrong? Or do I really need to do it from a JSP?

Reading the JSTL code, I found references to a LocalizationContext and think I need to set one. I couldn't quite figure out exactly how it fits into the picture or how to set one, though.

Was it helpful?

Solution

you need the 2nd:

3 ways to set JSTL locale: /as well as default application resource bundle, time zone, and data source/

  1. Set by a JSTL action – this allows specification of scope by the scope attribute.

    <fmt:setLocale value="en_US" scope="session"/>
    
  2. Set Programmatically – allows specification of scope via the Config API.

    import javax.servlet.jsp.jstl.core.Config;
    (...)
    Config.set( session, Config.FMT_LOCALE, new java.util.Locale("en", "US") )
    // or Locale.forLanguageTag("en-US") (java 1.7 and later)
    
  3. Set by Context Initialization Parameters – specifies value used if setting not found in any of the standard scopes.

    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
        <param-value>en_US</param-value>
    </context-param>
    

jstl-quick-reference (PDF)

OTHER TIPS

You can just use EL in <fmt:setLocale>. It doesn't need to be a hardcoded value or something.

Here's an example:

<c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" />
<fmt:setLocale value="${language}" />

If the language was supplied as request parameter with name language, then it will be set. Else if the language was already previously set in the session by attribute name language, then stick to it instead. Else use the user supplied locale in the request header.

If you do a session.setAttribute("language", language) in your filter code, then it will be used -if no request parameter is been set.

See also:

As far as I know, 'javax.servlet.jsp.jstl.fmt.locale' is overridden by the browser's locale. JSTL uses the browser's locale and if that's not found, it uses a fallback locale. So you can set a request attribute to specify that locale. Add this line to your controller

request.setAttribute("javax.servlet.jsp.jstl.fmt.fallbackLocale.request", "en-us");

Using this will set the locale which JSTL will use. Note the .request in the attribute name, if you set this attribute to some other scope, you'll have to use different suffix. For HttpSession the suffix is .session, for ServletContext the suffix is .application

If you are dependent on data from DB, may be there is better way to insert this logic into your 'router' or 'controller' (depends on which framework are you using). Just extend url with parameter ?lang='en'

Hope this helps

There is another way. In the servlet, you can set the locale by creating a session attribute, like so:

request.getSession().setAttribute("javax.servlet.jsp.jstl.fmt.locale.session", "ko-KR");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top