You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Christian Balzer <ch...@gmail.com> on 2017/07/12 23:01:20 UTC

org.apache.struts2.interceptor.I18nInterceptor seems to work only once + can defaulting to accept headers (and impacting on number/date parsing) be disabled?

Hi all,

I joined a project recently that makes use of Struts 2, and was tasked
with enabling internationalisation for it. I'm completely new to the
framework, and the project has organically grown over the years -
which means the project has a multitude of interceptors and chains
configured (some interceptors even seem to be called more than once by
the same chain), which might interfere with each other. So please bear
with me.

After spending some time bringing the project to the latest version of
Struts (and dealing with several breaking changes, mostly on the
Struts tags level), I have added the I18nInterceptor, as described on
[1] and added the following two parameters to it:
parameterName=language
localeStorage=session

Our resource bundle has an English default and a "de" properties file.

I also set ParametersInterceptor's excludeParams to "language" as per
[2], to avoid getting errors about my actions not having a "language"
setter. (For some reason, that appeared in the log, where I would have
expected it, albeit not as an ERROR, and on the page itself, which
prompted me to disable it.) Was that the right thing to do, or
superfluous?

When I set my "default" browser language to German, and call the page,
it loads the German text all right (so L10n of text works).
When I append the page's URL by ?language=en, it switches back to
English, which is great.
Sadly. this only seems to work exactly once per session. When I then
try to call ?language=de again, it stays English.
That's problem number one.

Problem number two is that I would prefer the interceptor to not check
the accept header, i.e. to ignore the browser.
Part of the reason is that the project owners always want to display
English, unless another language is explicitly chosen via URL
parameter. But mainly, we use number and date parsing in a lot of
places, and that depends on a British locale (i.e. en_GB, or de_GB;
the JS front-end doesn't check the user's locale, and calendar widgets
etc. all use British formats). A colleague of mine accessed the test
server after we had enabled the interceptor, and his browser had en_US
set as the first language in his accept header. Let's just say it
didn't go well, because our app didn't know what to make of the 12th
day of the 31st month anno 2017... (Ideally, we'd go for full g11n,
i.e. i18n of everything, not just text messages, but we won't have
time for it for the foreseeable future. Instead, for the immediate
future, we'd like maybe to extend the interceptor to only accept
locales from a predefined list (forcing the country to GB) - or only
use the locale for getText() [3] and nothing else...) Is there a
(fairly straightforward) way to disable the accept header fallback?

Last but not least, I have been unable to get debug output from either
of the two interceptors mentioned [4]...

I'd really appreciate if anyone could nudge me into the right
direction - especially regarding the "works once, but only once"
problem.

Kind regards,
Christian

P.S.: If all else fails, I thought I might try to use a custom-made
language switch similar to [5]...?

1) https://struts.apache.org/docs/i18n-interceptor.html
2) https://struts.apache.org/docs/parameters-interceptor.html
3) https://struts.apache.org/docs/localization.html
4) https://stackoverflow.com/questions/45065459/how-do-i-configure-log4j-to-log-messages-for-a-package-below-the-rootloggers-lo
5) https://www.mkyong.com/struts/struts-internationalizing-or-localization-example/

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


Re: org.apache.struts2.interceptor.I18nInterceptor seems to work only once + can defaulting to accept headers (and impacting on number/date parsing) be disabled?

Posted by Christoph Nenning <Ch...@lex-com.net>.
> Hi all,
> 
> I joined a project recently that makes use of Struts 2, and was tasked
> with enabling internationalisation for it. I'm completely new to the
> framework, and the project has organically grown over the years -
> which means the project has a multitude of interceptors and chains
> configured (some interceptors even seem to be called more than once by
> the same chain), which might interfere with each other. So please bear
> with me.
> 
> After spending some time bringing the project to the latest version of
> Struts (and dealing with several breaking changes, mostly on the
> Struts tags level), I have added the I18nInterceptor, as described on
> [1] and added the following two parameters to it:
> parameterName=language
> localeStorage=session
> 
> Our resource bundle has an English default and a "de" properties file.
> 
> I also set ParametersInterceptor's excludeParams to "language" as per
> [2], to avoid getting errors about my actions not having a "language"
> setter. (For some reason, that appeared in the log, where I would have
> expected it, albeit not as an ERROR, and on the page itself, which
> prompted me to disable it.) Was that the right thing to do, or
> superfluous?
> 
> When I set my "default" browser language to German, and call the page,
> it loads the German text all right (so L10n of text works).
> When I append the page's URL by ?language=en, it switches back to
> English, which is great.
> Sadly. this only seems to work exactly once per session. When I then
> try to call ?language=de again, it stays English.
> That's problem number one.
> 
> Problem number two is that I would prefer the interceptor to not check
> the accept header, i.e. to ignore the browser.
> Part of the reason is that the project owners always want to display
> English, unless another language is explicitly chosen via URL
> parameter. But mainly, we use number and date parsing in a lot of
> places, and that depends on a British locale (i.e. en_GB, or de_GB;
> the JS front-end doesn't check the user's locale, and calendar widgets
> etc. all use British formats). A colleague of mine accessed the test
> server after we had enabled the interceptor, and his browser had en_US
> set as the first language in his accept header. Let's just say it
> didn't go well, because our app didn't know what to make of the 12th
> day of the 31st month anno 2017... (Ideally, we'd go for full g11n,
> i.e. i18n of everything, not just text messages, but we won't have
> time for it for the foreseeable future. Instead, for the immediate
> future, we'd like maybe to extend the interceptor to only accept
> locales from a predefined list (forcing the country to GB) - or only
> use the locale for getText() [3] and nothing else...) Is there a
> (fairly straightforward) way to disable the accept header fallback?
> 
> Last but not least, I have been unable to get debug output from either
> of the two interceptors mentioned [4]...
> 
> I'd really appreciate if anyone could nudge me into the right
> direction - especially regarding the "works once, but only once"
> problem.
> 
> Kind regards,
> Christian
> 
> P.S.: If all else fails, I thought I might try to use a custom-made
> language switch similar to [5]...?
> 
> 1) https://struts.apache.org/docs/i18n-interceptor.html
> 2) https://struts.apache.org/docs/parameters-interceptor.html
> 3) https://struts.apache.org/docs/localization.html
> 4) https://stackoverflow.com/questions/45065459/how-do-i-configure-
> log4j-to-log-messages-for-a-package-below-the-rootloggers-lo
> 5) https://www.mkyong.com/struts/struts-internationalizing-or-
> localization-example/
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 


Hi,


> I also set ParametersInterceptor's excludeParams to "language" as per
> [2], to avoid getting errors about my actions not having a "language"
> setter. (For some reason, that appeared in the log, where I would have
> expected it, albeit not as an ERROR, and on the page itself, which
> prompted me to disable it.) Was that the right thing to do, or
> superfluous?

Such messages appear on pages when struts devMode is enabled. Thats great 
for development but should be disabled for production.

See https://struts.apache.org/docs/devmode.html

The docs of I18nInterceptor say default value of parameterName is 
"request_locale" and that one is in ParametersInterceptor's excludeParams 
by default. As you changed I18nInterceptor's parameterName it makes sense 
to put your new value in ParametersInterceptor's excludeParams, too.



> Sadly. this only seems to work exactly once per session. When I then
> try to call ?language=de again, it stays English.
> That's problem number one.


Your obvious choices are to use the other storage mechanism (cookie) or 
not store locale at all. In that case your app must add parameter 
"request_locale" in each request (GET and POST).

After a short look at I18nInterceptor's code I don't think this behavior 
is intended. It might be that your app has special circumstances to 
trigger such behavior or it might be a struts bug. Please try to debug 
that case or enable logging (see below).



> Is there a
> (fairly straightforward) way to disable the accept header fallback?

That is implemented in class Dispatcher. The way to override it is to 
configure a struts default locale. You can do that e.g. in struts.xml or 
struts.properties with key "struts.locale".

See https://struts.apache.org/docs/constant-configuration.html


> Last but not least, I have been unable to get debug output from either
> of the two interceptors mentioned [4]...

I18nInterceptor logs a lot on level DEBUG. It's full classname is 
org.apache.struts2.interceptor.I18nInterceptor.

How debug logging is enabled depends on your logging library. For log4j1 
you could put this in your log4j.properties:

log4j.logger.org.apache.struts2.interceptor.I18nInterceptor=DEBUG

For log4j2 it would be:

<Logger name="log4j.logger.org.apache.struts2.interceptor.I18nInterceptor" 
level="debug"/>



Regards,
Christoph

This Email was scanned by Sophos Anti Virus