struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From John Sanda <jsa...@redhat.com>
Subject Re: bug with RequestProcessor.processLocale() in struts 1.2.9?
Date Thu, 15 Jun 2006 15:49:59 GMT
Niall Pemberton wrote:

> On 6/15/06, John Sanda <jsanda@redhat.com> wrote:
>
>> 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!
>
>
> If you want to use the options set/selected in the browser to control
> Locale then you need to switch Struts's Locale processing off (the
> default is on) and your comment "No, our app does not have this
> configured - jsanda" is probably not true.
>
> http://struts.apache.org/struts-action/userGuide/configuration.html#controller_config

>
>
> <controller locale="false" />
>
> The alternative is to use Strut's Locale processing and provide the
> facility in the webapp to switch Locale (struts-examples webapp does
> this) and to ignore whats in the browser.
>
> Say you have a webapp that supports English, French and German - if
> you use the browser settings, then a Spanish user will get the default
> which may not be the best choice for them. If you have an action to
> switch between the three supported languages, then they can choose the
> best option themselves.
>
> Niall

I wound up explicitly setting the locale in the session as a work around 
for my bug, but now I see that there is no need for that. And when the 
locale option in the controller config is turned off, 
RequestUtils.getUserLocale() will in fact return the locale as specified 
in the request and all is well. Thanks for the clarification.

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


-- 
- JS


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


Mime
View raw message