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

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Christian Balzer
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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Christoph Nenning
> 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: [hidden email]
> For additional commands, e-mail: [hidden email]
>


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
Loading...