Blog do projektu Open Source JavaHotel

poniedziałek, 16 kwietnia 2012

Google App Engine and getLocalizedMessage

Problem
I found a nasty problem in Google App Engine - look at this JSP code.
Sometimes it is very useful to get localized message in JSP scriplet. For instance,  to use it as a parameter to other java method or as a attribute value to a JSP tag.
<%
  String hello = LocaleSupport.getLocalizedMessage(pageContext, "Hello");
  Object params[] = { "John" };
  String helloJohn = LocaleSupport.getLocalizedMessage(pageContext, "HelloName",params);  
%>
But the code above does not work in Google App Engine (run). What is worse - it works in development mode but after deploying to Google App Engine one gets into trouble. So it is not easy to recognize this issue, particularly in a larger project.

/notworkinghello.jsp
java.lang.NoClassDefFoundError: org/apache/taglibs/standard/tag/common/fmt/BundleSupport
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:143)
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:63)
 at org.apache.jsp.notworkinghello_jsp._jspService(notworkinghello_jsp.java:72)
......
What is more interesting, JSTL Code fmt:message tag is working as expected.
Solution
The only solution I found is to use BundleSupport class directly and create custom getMessage method.
It looks as below:
import java.text.MessageFormat;
import java.util.ResourceBundle;

import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;

import org.apache.taglibs.standard.tag.common.fmt.BundleSupport;

public class GetLocalizedMessage {

 /**
  * Replacement for LocaleSupport.getLocalizedMessage method in JSP pages
  * Before calling set fmt:setLocale and fmt: setBundle
  */
 
 private GetLocalizedMessage() {

 }

 /**
  * Gets localized message (also MessageFormated) from I18N bundle
  * @param pageContext PageContext
  * @param key Message key
  * @param params List of parameters for MessageFormat (if exists) 
  * @return localized message
  */
 public static String getMessage(PageContext pageContext, String key,
   String... params) {

  LocalizationContext loca = BundleSupport.getLocalizationContext(
    pageContext);
  ResourceBundle bundle = loca.getResourceBundle();
  String message = bundle.getString(key);
  if (params.length == 0) {
   return message;
  }
  String mess = MessageFormat.format(message, params);
  return mess;
 }

}

Then instead of getLocalizedMessage method from LocaleSupport class use method above directly - as source below.
<%
  String hello = GetLocalizedMessage.getMessage(pageContext, "Hello");
  String helloJohn = GetLocalizedMessage.getMessage(pageContext, "HelloName","John");
%>
The rest of the JSP page can be left without change. Finally the JSP page works as expected also in Google App Engine.
Source code 
The whole project is available here.

Brak komentarzy:

Publikowanie komentarza