I have created the following ResourceBundle in Java which reads from the correct MessegesBundle_en_GB.properties file:
ResourceBundle labels =
ResourceBundle.getBundle("MessegesBundle",new Locale( "en", "GB"));
labels.getString("Test");
However when I try using another language (Scottish Gaelic) it simply defaults back to en_GB
ResourceBundle labels =
ResourceBundle.getBundle("MessegesBundle",new Locale( "gd", "GB"));
system.out.println(labels.getLocale()); // returns en-GB
labels.getString("Test");
Looking through the list of Available Locales from Locale.getAvailableLocales(); and "gd" doesn't appear.
Does this mean I can't use ResourceBundle for I18N or is there a way of either adding Gaelic or forcing ResourceBundle to use the correct properties file?
Thanks
The locales returned by getAvailableLocales() are not very important as you can create new ones the way you did: new Locale( "gd", "GB").
As stated in the Locale java docs the locale main purpose is to identify resources: resource bundles, number formats, etc. The strings identifying the Locale are not even validated upon creation.
My guess is that you don't have the MessegesBundle_gd_GB.properties resource available in the classpath.
The server needs to have that charset language installed to load it, I suppose you could "force" it however when serving a page but you would need to pick up information specificaly from the user as a request for that page language to be assigned.
Related
I have 2 string files to 2 languages in my android app, PT and EN. But I need to know which is the string file in use because I need to add in my SQLite database the current language in use.
Actually, I'm using this code to detect the current language in my SQLite database, but this function only works if the user changes the language manually in config screen. because I don't know how to get the first language selected when the user opens the application in the first time.
if(!dbl.selectIni().getCurrent_lang().equalsIgnoreCase("system")){
String languageToLoad = dbl.selectIni().getCurrent_lang();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
You can use:
Locale.getDefault().getLanguage();
Or use the following code if you want to get the Locale when user change language from setting:
defaultLocale = Resources.getSystem().getConfiguration().locale;
It gets the system locale, no matter which default locale is set for the app/activity.
Read https://developer.android.com/reference/android/content/res/Resources.html#getSystem%28%29
But please remember that Resources.getSystem() references to the system resources and might cause a crash if used incorrectly.
For other option you can use the following:
Locale current = getResources().getConfiguration().locale;
From https://stackoverflow.com/a/14389640/4758255
And please be noted that this has been deprecated in the Configuration class, see the latest docs for this advice: locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor.
I'm working on one portal product. I'm facing problem in making it internationalized. I'm
using following code
Locale locale = new Locale(languageHashMap.get(preferredLanguageId));
ActionContext.getContext().setLocale(locale);
session.setAttribute(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, locale);
for setting the locale.
For one time it is working fine but when I change the langauge again the change the language again, the change is not reflecting in all the pages. Still get the changes made by the last language only.
Any help will be appreciated
I guess the locale is not setting properly.
Try out the following code :
create one map
private static Map<Locale, ResourceBundle> messageBundles = new Hashtable<Locale, ResourceBundle>();
and then use the following:
Locale requestLocale = ActionContext.getContext().getLocale();
ResourceBundle rb = messageBundles.get(requestLocale);
and then put that resource bundle in the request scope.
its working fine....
Locale locale = new Locale(languageHashMap.get(preferredLanguageId));
ActionContext.getContext().setLocale(locale);
session.setAttribute(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, locale);
I try to use i18n localization but I have stuck.
If I use:
I18n i18n = new I18n(slingRequest);
i18n.get("myMessage");
I always get the english message for key: myMessage.
In accept-language header I can see these values: de,en;q=0.5
but:
request.getLocale() returns: en
request.getLocales() returns: en
If I use code below everything is good:
Locale myLocale = new Locale("de");
ResourceBundle resourceBundle = slingRequest.getResourceBundle(myLocale);
I18n i18n = new I18n(resourceBundle);
Why don't cq read "accept-language" request headers?
ps: I use standalone cq jar...
Thanks in advance!
CQ/Sling (as of 5.6) does not read the Accept-Language header for the locale you get via slingRequest.getLocale() (or slingRequest.getResourceBundle(null) which implicitly uses that locale), instead it uses the user's language setting (~/preferences/#language in the JCR) or a configurable default (1).
The reasoning is that a fixed setting is much stabler, also when using different browsers across devices, than guessing the language header.
But it's extensible: you can hook in a custom org.apache.sling.i18n.RequestLocaleResolver service (with a higher service rank), which is the service that provides the value for slingRequest.getLocale() (2). This could also take the accept language into account; it gets access to the underlying servlet request object, which should give you the Accept-Language header value in getLocale() and getLocales() (at least the built-in servlet engine in CQ does that since 5.4).
(1) Configure default locale on this service: http://localhost:4502/system/console/configMgr/org.apache.sling.i18n.impl.JcrResourceBundleProvider
(2) Sling's I18nFilter which you probably have seen in stack traces already does all the magic and wraps the request to provide the slingRequest.getLocale() and slingRequest.getResourceBundle() implementations using the RequestLocaleResolver and ResourceBundleProvider services
Is the first code example copy pasted? If the sample is pasted from your code, then a typo in your key may be the issue because the language key in your example is "myMesage" and not "myMessage" as indicated later in your post.
What is the correct way of knowing operating system language (locale) from java code?
I have tried
Locale.getDefault()
System.getProperties("user.language")
etc.
but they are not correct nothing actually displays the "System Locale" which is available by the command "systeminfo" in windows.
Please help.
The Windows XP systeminfo command displays lots of stuff, but the relevant information is this:
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
To get equivalent information in Java, use Locale.getDefault() to get the Locale that Java is using, and use methods on the Locale object such as getCountry(), getLanguage() to get details. The information is available using ISO codes and as human readable/displayable names.
Note that Locale.getDefault() gives you the locale that Java picks up from the environment when it starts, this may or may not be the same as the "system" locale. To definitively get the "system" locale in Java you would need to do platform specific things. IMO, it is simpler to make sure that Java gets started with the system locale ... if you really need that information.
UPDATE: Apparently, Java 7 has changed the way that the locale information used by getDefault() is determined on Windows; see https://stackoverflow.com/a/8319889/139985
What about
System.getProperty("user.country");
System.getProperty("user.language");
Returns in my case
user.country=DE
user.language=de
You easily can generate the locale from this information. Local is 'language'_'country' so in my case
de_DE
How about using the default locale?
Locale locale = Locale.getDefault();
String lang = locale.getDisplayLanguage();
String country = locale.getDisplayCountry();
This returns me my current language and country as per the Windows systeminfo command. Is this what you're looking for? (If you want the 2-character codes for language/country, you can just use getLanguage() or getCountry()).
To be precise, you can try following code:
public Locale getLocale() {
if (this.locale == null) {
this.locale = new Locale(System.getProperty("user.language"), System.getProperty("user.country"));
}
return this.locale;
}
How to provide multi language support through JSP/Servlet? How to include static data of different languages at run time on basis of language selected?
In a "plain vanilla" JSP/Servlet application, the best solution is the JSTL fmt taglib. (just drop jstl-1.2.jar in /WEB-INF/lib) How to use it is covered in Oracle Java EE 5 tutorial part II chapter 7 and in this answer: How to internationalize a Java web application?.
If you're using a MVC framework such as Oracle JSF or Apache Struts, then you need to consult its specific documentation using keywords "internationalization" (i18n) or "localization" (l10n). In most cases they also provides specific tags for that, such as <f:loadBundle> in case of JSF, which in turn is covered in Oracle Java EE 5 tutorial part II chapter 15.
Those i18n tags already checks the default language/locale by ServletRequest#getLocale() (you don't need to do it "low-level" by checking the header as one suggested before --which would involve more work parsing the header as per the HTTP spec). You can let the user choose the language itself (dropdown?) and store it in the session scope and instruct those taglibs to use it. Here's an example with JSTL fmt taglib:
<fmt:setLocale value="${someSessionBean.locale}" />
..where ${someSessionBean.locale} can return en, en_US, en_UK, etc. Those are in turn used by the java.util.ResourceBundle API to load the localized text (you don't need to create/load the ResourceBundle itself, the taglibs already do that, just read the linked javadoc to learn a bit more about how it works).
If you want the language available as first pathinfo part of URL (such as http://example.com/en/, which is best for SEO), then you can best use a Filter for this which listens on /*, checks the pathinfo, splits the language part from it, stores/compares it as/with session value and forwards the request without language part in pathinfo further to the desired front controller.
There are several important aspects to this issue. The first part is determining each request's locale. You can use something like this:
HttpServletRequest req ...;
String browserLocale = req.getHeader("Accept-Language"); // typically something like 'en'
Next, you need to decide how to manage the site's localized content. The most Java-like (not necessarily the best) approach is to externalize all messages using a ResourceBundle. You can learn about the core Java facilities for I18N, G13N in their Isolating Locale Specific Data tutorial.
Using only this approach is quite poor in my opinion. Different languages' content size differently, match better with different layouts, etc. So you can completely eliminate resource bundles (if you don't have a lot of multi-locale data) or augment the approach by using XSLT or other templating that is locale specific.
One very performant but high-development overhead approach is to use a servlet filter to redirect traffic to language- (or locale-) specific subsites. In this case, anyone hitting http://my.domain.fake/xyz would get redirected to http://my.domain.fake/en/xyz
Finally, it is worth noting that most of the serious web frameworks have their own I18N support. Their approaches differ based on the framework philosophy.
We can to create messages.properties, messages_????.properties and to place this files into /scr/java directory. (where ???? - en_US, ru_RU and other)
Example lines into messages.properties:
About = About
Buy = Buy
Company = Company
ContactUs = Contact Us
Then to paste into jsp file for example lines:
Locale locale = Locale.getDefault();
String lng = locale.getCountry();
session.setAttribute( "language", lng);
if (lng.equals( "UA"))
locale = new Locale( "uk", "UA");
else if (lng.equals( "RU"))
locale = new Locale( "ru", "RU");
else
locale = Locale.US;
ResourceBundle boundle = ResourceBundle.getBundle( "messages", locale);
for (Enumeration e = boundle.getKeys(); e.hasMoreElements(); ) {
String key = (String) e.nextElement();
String s = boundle.getString(key);
session.setAttribute( key, s);
}
Now you can paste ${name} into next jsp code (${About}, ${Buy}, ...).