CQ 5.5 i18n and accept-lanugage header - java

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.

Related

OVH JAVA API using Get request with parameters

am trying to create a web interface to interact with OVH's telephony API ovh telephony api using the official JAVA wrapper OVH java wrapper.
I am trying to use a GET endpoint with parameters. this is the endpoint:
GET /telephony/{billingAccount}/line/{serviceName}/statistics
Parameters:
timeframe: string;
type : string
This is how I am doing the call:
api.get("/telephony/{myBuildingAccount}/line/{myServiceNumber}/statistics", "timeframe=daily&type=maxDelay", true);
But I am getting an error 400 bad signature.
Could someone help me with this ?
The API of the java wrapper specifies that the api.get method receives as the second parameter (in the three parameters version of api.get) the GET body; but you are passing a string containing the URL parameters:
api.get("/telephony/{ACCT}/line/{NUM}/statistics", "timeframe=daily&type=maxDelay", true);
Since the request you need does not require a body and does require the parameters in the URL, you need to use the following invocation:
api.get("/telephony/{ACCT}/line/{NUM}/statistics?timeframe=daily&type=maxDelay", true);
Pay attention that {ACCT} and {NUM} must be replaced by the actual account and service number values in that first string. Also, notice the parameters are appended directly into the string URL.
Hope this helps.

Is there any method to create radio button in com.ibm.cics.server

The java API for CICS is here. Does anyone know if there any method to put a couple of radio buttons to a web form using this API?
Here's my code to create radio button
HttpRequest req = HttpRequest.getHttpRequestInstance();
String msg = "ZEUSBANK ANTI-FRAUD CHECK BY SHE0008.<br> "
+ "When investigation is complete. Tick the check box and submit.<br>";
String template = "<form><input type=\"radio\"> YES<br><input type=\"radio\"> NO<br></form>";
HttpResponse resp = new HttpResponse();
Document doc = new Document();
doc.createText(msg);
doc.appendFromTemplate(template);
resp.setMediaType("text/plain");
resp.sendDocument(doc, (short)200, "OK", ASCII);
But when I run it on a browser, it print plain text and doesn't convert html tag.
Fixed it, I just change media type from text/plain to text/html and it works.
As you've already discovered, you needed to send the request with the text/html content type.
If you're planning to do more Java web-based work through CICS Java, you might want to investigate the embedded WebSphere Liberty. It adds support for Java EE features, which includes JSF, JSP and Servlets, which can make web development in Java a lot easier.
Tri,
I haven't used CICS for 15 years, so I doubt I'm an expert anymore. But looking quickly at the API, it seems like all the presentation logic would be in your regular Java code. You would then format appropriate messages and invoke the CICS API to update the server & get a response.
There doesn't seem to be any 'BMS-related' methods at all (which is a good thing).
The only 'field' method I see is com.ibm.cics.server.FormField but that only has get() methods, not set().
Are you just starting with Java CICS, or are you just stuck on this particular issue? If you have some sample code of what you are trying, post it so we can see if anyone has any ideas.
HTH, Jim

Tapestry : Start page use english locale instead of default locale

We built a website with Tapestry 5.1.0.5 and we encounter, sometimes, a missing key problem when we hit the start-page.
This problem appeared only 4 times, this is a random issue.
Actual configuration:
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "fr"); => so the default local is fr and not en
configuration.add("tapestry.start-page-name", "Accueil"); => so when we hit / tapestry redirects us on /accueil
Here is the problem we sometimes see:
When hitting / tapestry searches keys in *_en.properties instead of *_fr.properties but if we hit /accueil tapestry searches keys in *_fr.properties.
Trace log :
Caused by: java.lang.NumberFormatException: For input string: **"[[missing key: prehome.store.opening.delay]]"**
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.lang.Integer.parseInt(Integer.java:497)
at XXXXXXX.tapestry.components.overlayer.StoreOverlayer.initStoresAndRegions(StoreOverlayer.java:652)
at XXXXXXX.tapestry.components.overlayer.StoreOverlayer.setupRender(StoreOverlayer.java)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$SetupRenderPhase.invokeComponent(ComponentPageElementImpl.java:184)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$AbstractPhase.run(ComponentPageElementImpl.java:164)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.invoke(ComponentPageElementImpl.java:933)
... 94 more
01-02-2012 11:55:52:979 23120252 ERROR org.apache.tapestry5.internal.services.InternalModule.PagePool - Page Page[Accueil en] is dirty, and will be discarded (rather than returned to the page pool).
Has anyone had this problem?
Do you know why when we hit the start-page, tapestry use en locale instead of our default locale fr?
I'd say that if you want to ensure that default locale is French, then just rename all message_fr.properties to message.properties.
Also please take a look into browser settings. If your browser is requesting English version of the site, then Tapestry obeys. You may override that behavior, but I'd suggest treating that like a feature (as user is getting site related to his preference) rather than a bug.
And last hint, if you are supporting more than one language then list them all in supported locales constant.
-= Edit =-
it's also probably worth checking do you have the global messages.properties file in English or in French

Google Translator API and many translation for one word

I am using google-api-translate-java-0.92.jar.
Translate.setHttpReferrer("http://translate.google.com/");
try {
String translation = Translate.execute("arrangement", Language.ENGLISH, Language.UKRANIAN);
System.out.println(translation);
} catch (Exception e) {
System.out.println(e.getMessage());
}
But I get only one translation.
I go to page http://translate.google.com/ and It gives me multiple translation.
How can I get multiple translation from my code?
I don't believe you can...
Looking at the soucre, it builds up the following URL:
http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&langpair=en|uk&q=arrangement
which when you look at the JSON response, returns:
{"responseData": {"translatedText":"Композиція"}, "responseDetails": null, "responseStatus": 200}
As you can see, this is only returning a single word. The dictionary lookup on the google translate page must be an additional call to a different service (not part of the translate service)
EDIT
Using firebug, you can see the request that is being made by the translate page, and you get this URL:
http://translate.google.com/translate_a/t?client=t&text=arrangement&hl=en&sl=en&tl=uk&multires=1&otf=2&pc=0&sc=1
Which returns this:
[[["Композиція","arrangement","Kompozytsiya"]],[["noun",["розташування","розміщення","домовленість","аранжування","упорядкування","механізм","оформлення","пристрій","систематизація","монтаж","пристосування","урегулювання","плани","згода","залагода","розв'язання","порозуміння"]]],"en"]
However, this extended URL format is not supported by the translate JAR you are using (at least I can't find it in the source on google code), is not part of the googleapis subdomain, and I'm not even sure it's for public consumption or that calling it directly doesn't violate Googles T&Cs.
But that's how they generate the dictinary list anyway...
From Google Translate API FAQ (checked: 16 November 2013)
Is it possible to get multiple translations of a word?
The answer:
No. This feature is only available via the web interface at
translate.google.com
source: https://developers.google.com/translate/v2/faq#technical
There is an open enhancement request for this functionality. So it doesn't look like you're doing anything wrong; the API just doesn't expose that functionality.

MUlti Language support in JSP/Servlet

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}, ...).

Categories

Resources