*Problem: *
Required ability to have access to GWT client
com.google.gwt.i18n.client.Messages files on server side(e.g. inside
Servlet).
*Problem reason: *
In my case I needed to generate the PDF representation of the web page +
save some string values in DB(when someone posts comment).
*Desired behaviour*:
Have a single MessageResource provider that can be executed from both server
side and from client side:
*Solution:
*
1. First of all *make sure that all GWT message resources are generated
from *.properties file via com.google.gwt.i18n.tools.I18NSync tool*(or
you have to synchronise i18n .properties files with GWT message interfaces
all the times). Otherwise, if you just using interfaces without using
*.properties files, this approach will not work.
2. Now, let's *educate the server how to read GWT i18n *.properties*:
1. I am using spring framework as server side, so in this example we
will educate Spring where the GWT's i18n *.properties are stored in the
app:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
<value>classpath:error_messages</value>
<value>classpath:/blabla/project/client/resources/i18n/messages/GlobalRes</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
the classpath:/blabla/project/client/resources/i18n/messages/GlobalRes
is full path to GlobalRes.properties file. Make sure you include this
file
in classpath when yo compile your project.
2. Basically, after telling spring
ReloadableResourceBundleMessageSource where to take the resources is
pretty
enough to have GWT messages being accessed on server side, by just
injecting
messageSource into any place on server and using
messagesCourse.getMessage("messageCode",args[],locale). But this is not
what
we want to achieve. The aim is to have the same message resource provider
that can be executed on server and on client side the same way.
3. So next, let's just create this Messages Provider that can be
executed on both client and on server side:
public class MessageResourceProvider {
public static GlobalRes GLOBAL_RES;
public static GlobalRes SERVER_GLOBAL_RES;
static {
try {
GLOBAL_RES = GWT.create(GlobalRes.class);
} catch (Exception e) {
}
}
public static GlobalRes getGlobalRes() {
if (GLOBAL_RES != null) {
return GLOBAL_RES;
} else {
return SERVER_GLOBAL_RES;
}
}
}
First of all, make sure that MessageResourceProvider is stored under *.*
client.** package, so GWT client side will be able to access it. So here
we have two instances for providing resources: one for server part, the
other one for client side. With client side everything is clear: we just try
to call GWT.create(GlobalRes.class) in static block and if it's successfully
executed(which actually means it executed on client side) then the
getGlobalResources will return client version of GlobalRes.
But what about SERVER_GLOBAL_RES? Where should it come from? Obviously -
it should come from server.
4. Ok, let's *tell server part to how inject SERVER_GLOBAL_RES into
MessageResourceProvider wher the server starts*.
in order to do that I just added listener in my* web.xml*
<listener>
<listener-class>
org.kuali.lum.cmi.server.util.CmiServletListener
</listener-class>
</listener>
so application will call this listener at startup time.
the listener code is very simple:
public class CmiServletListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServerMessageResourceFactory serverMessageResourceFactory =
(ServerMessageResourceFactory)
WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean("serverMessageResourceFactory");
MessageResourceProvider.SERVER_GLOBAL_RES =
serverMessageResourceFactory.getGlobalRes();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
As you see at startup time I just set MessageResourceProvider's
SERVER_GLOBAL_RES which I take from
serverMessageResourceFactory.getGlobalRes().
5. So this is almost it, except I haven't described the most tricky and
interesting part: *how the serverMessageResourceFactory.getGlobalRes()
will return the com.google.gwt.i18n.client.Messages resources instance that
can de executed from server side and why hadn't we use messageResources,
that we've created at 2nd step?:
*The answer is below:
public class ServerMessageResourceFactory {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return
messageSource.getMessage(method.getAnnotation(LocalizableResource.Key.class).value(),
args, null);
}
};
private ReloadableResourceBundleMessageSource messageSource;
public GlobalRes getGlobalRes() {
return (GlobalRes)
Proxy.newProxyInstance(GlobalRes.class.getClassLoader(), new
Class[]{GlobalRes.class}, handler);
}
public void setMessageResource(ReloadableResourceBundleMessageSource
messageSource) {
this.messageSource = messageSource;
}
}
The ServerMessageResourceFactory contains two functions two fields that
do all the tricks:
- the getGlobalRes() returns proxy for GlobalRes which is handled by
handler
- inside the handler we easily can extract the message key value(*
method.getAnnotation(LocalizableResource.Key.class).value()*) and
passed arguments(*args*).
- with messageSource, which already knows how to get the GWT resources
from i18n *.property files we jast take all GWT client resources.
*Result:
*As a result now, we have MessageResourceProvider.getGolbalRes() that can be
executed from both: server and client side. So you never should care
wherethere you using resources from client side or from server side. Just
call MessageResourceProvider.getGolbalRes() to get access to the app message
resources.
--
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-web-toolkit/-/9q2i3rWbtI4J.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.