Thursday 2 January 2014

Spring Resource Bundle With ReloadableResourceBundleMessageSource In Static Method

2 different ways to do this and one of them is a little bit harder to develop. I start with the hard way first, but in these examples you must need some environmental things:

My ResourcesBundle.properties file is directly inserted in the classpath.

My applicationContext.xml file is directly inserted in the WebContent/WEB-INF.



First Method: With Application Context

This is the hard way of using Message Source with spring. You must define a bean like this in the applicationContext.xml:

<bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:ResourcesBundle</value>
            </list>
        </property>
        <property name="cacheSeconds" value="1"/>
        <!-- to load resource file from outside application  -->
        <!-- <property name="basename" value="file:E:/properties/ResourcesBundle" /> -->
    </bean>


Now we come to Java part.. If you create a bean via application context and ‘Autowire’ it into the class and then try to use it in some static methods, I can say you’ll have bad time!!! Because, static method will be loaded into system before the bean and you’ll get a every Java developer’s favourite exception: NullPointerException. We need an extra class to create bean instance. And here we go:

Here is the ApplicationContextProvider.java

package com.mahesh.resource.util;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;



@Component
@Scope("singleton")
public class ApplicationContextProvider implements ApplicationContextAware {
    private static final Logger LOG = Logger.getLogger("ApplicationContextProvider.class");
    private static ApplicationContext context;

    /**
     * Returns context
     * @return
     */
    public static ApplicationContext getContext() {

        if (context != null) {
            return context;
        } else {
            LOG.warn("The Spring application context is not yet available.");
            throw new IllegalStateException("The Spring application context is not yet available.");
        }
    }

    /**
     * Sets Context
     * @param applicationContext
     *
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {

        if (context == null) {
            ApplicationContextProvider.context = applicationContext;
        } else {
            LOG.warn("The application context provider was already initialized.");
           
        }
    }
}

Above, I introduce you our backup class ApplicationContextProvider. This class will help us to get beans from application context. And finally we get to our message provider class.

package com.mahesh.resource.util;

import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
 * This is a Message translator Class which reads Messages form Properties File
 */
@Component
@Scope("singleton")
public final class MessageTranslator {
    private static final Logger LOG = Logger.getLogger("MessageTranslator.class");

    public MessageTranslator() {
    }

    public static String getMessage(String key) {
        return getMessage(key, null);

    }

    public static String getMessage(String key, Object[] obj) {

        try {
            MessageSource bean = ApplicationContextProvider.getContext().getBean(MessageSource.class);
            return bean.getMessage(key, obj, "Default", null);
        } catch (Exception e) {
            LOG.warn("Unresolved key: " + key);
            return "Unresolved key: " + key;
        }
    }
}





There you go.. We create a class with static getMessage() method and it is ready to serve us. We can both use this class in our other java classes.

Second Method: Without Application Context

In this technic we only need a Java class. We will create our ResourceBundleMessageSource in this class and that’s all.. Here is a code sample:

package com.mahesh.resource.util;

import java.util.Locale;
import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")
public class MessageUtil {

    public static String getMessage(String key) {

        try {
            ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
            bean.setBasename("ResourcesBundle");
            return bean.getMessage(key, null, Locale.getDefault());
        }
        catch (Exception e) {
            return "Unresolved key: " + key;
        }

    }
   
    public static void main(String[] args) {
       
        System.out.println(MessageUtil.getMessage("user.name"));
    }
}

In this code, we create a ReloadableResourceBundleMessageSource instance and set its basename to ‘messages’. The rules I mention for applicationContext is still same here. If you directly look this method, you can scroll up and see what are the rules for setting up basename and Locale..

No comments:

Post a Comment