struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From John Sanda <jsa...@redhat.com>
Subject bug with RequestProcessor.processLocale() in struts 1.2.9?
Date Thu, 15 Jun 2006 14:41:58 GMT
I was working on a bug for a project using struts 1.2.9 involving 
internationalization and one of our subclasses of LookupDispatchAction. 
The bug initially seemed to be straightforward because we were getting 
exceptions with a familiar stacktrace that read something like,

missing resource in key method map
	at org.apache.struts.actions.LookupDispatchAction.getLookupMapName(LookupDispatchAction.java:230)


So the app supports a number of different locales, and we have 
locale-specific messages in different resource files. I have seen 
numerous posts to the mailing lists about these types of errors. The 
problem turned out to be a little more suttle than what I came across on 
the lists however. The bug manifests itself when the user switches 
locales in the browser between requests. I wound up looking through the 
source of LookupDispatchAction to figure out what was going on (which 
was cool because I learned a lot about Struts!).   Rather than trying to 
explain what was going on, let me jump right to the code I have 
questions about. I have added some of my own commments for 
clarification. Here is the implementation for 
RequestProcessor.processLocale().

    // called from RequestProcessor.process(HttpServletRequest request, HttpServletResponse
response)
    protected void processLocale(HttpServletRequest request, HttpServletResponse response)
{
        // Are we configured to select the Locale automatically?
        //
        // No, our app does not have this configured - jsanda
        if (!moduleConfig.getControllerConfig().getLocale()) {
            return;
        }

        // Has a Locale already been selected?
        HttpSession session = request.getSession();
        // on an initial request to the app, no locale will be in the session - jsanda
        if (session.getAttribute(Globals.LOCALE_KEY) != null) {
            return;
        }

        // Use the Locale returned by the servlet container (if any)
        //
        // OK, let's say that the initial request has a locale of en-us. Then
        // an en-us locale will be stored in the user's session with 
        // Globals.LOCALE_KEY as the attribute key. - jsanda 
        Locale locale = request.getLocale();
        if (locale != null) {
            if (log.isDebugEnabled()) {
                log.debug(" Setting user locale '" + locale + "'");

            }
            session.setAttribute(Globals.LOCALE_KEY, locale);
        }
    }


Prior to the user sending her next request, let's say she changes her 
locale settings to frech (fr). The next time processLocale() is called, 
it will find the locale in the session, but it will be en-us, which is 
the wrong  locale. If there is somewhere in the Struts code (that I 
missed) that flushes the locale from the session before sending the 
response to the client, then this isn't/shouldn't be an issue. And of 
course, if an altogether different RequestProcessor implementation is 
used, then this may not be an issue either. Where I found this problem 
manifesting itself is in the two following code snippets. The first is 
from RequestUtils.

    public static Locale getUserLocale(HttpServletRequest request, String locale) {
        Locale userLocale = null;
        HttpSession session = request.getSession(false);

        if (locale == null) {
            locale = Globals.LOCALE_KEY;
        }

        // Only check session if sessions are enabled
        if (session != null) {
            userLocale = (Locale) session.getAttribute(locale);
        }

        // Will this code ever get executed since RequestProcessor is always first
        // making sure that the locale is in the session? - jsanda
        if (userLocale == null) {
            // Returns Locale based on Accept-Language header or the server default
            userLocale = request.getLocale();
        }

        return userLocale;
    }


LookupDispatchAction (indirectly) calls RequestUtils.getUserLocale() 
from getLookupMapName(). Here is a portion of that method.

    // This method is called to perform locale-specific message lookups. - jsanda
    protected String getLookupMapName(HttpServletRequest request, String keyName, ActionMapping
mapping) throws ServletException {
        // Based on this request's Locale get the lookupMap
        Map lookupMap = null;

        synchronized(localeMap) {
            // getLocale() simply calls through to RequestUtils.getUserLocale(). - jsanda
            Locale userLocale = this.getLocale(request);
            // Based on my findings above, we have may a request with a french (fr) locale,
but
            // we will wind up with the lookup map for the en-us locale-specifc messages...not
good. - jsanda
            lookupMap = (Map) this.localeMap.get(userLocale);
            .
            .
            .
        }
        .
        .
        .
    }


I am not all that familiar with the Struts code; so, can someone shed 
some light on this for me and let me know whether or not this is in fact 
a bug. Thanks!

-- 
- JS


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Mime
View raw message