Get all message properties key value pairs as JSON for selected locale in Spring boot

Pratiyush Prakash
2 min readJan 3, 2022

--

Problem Statement

For internationalization we store all key value pairs as message properties in spring boot project such that our web component doesn’t have to store all the key value pairs for all the locales which we are supporting now or we will support in future. And based on which locale user selects we have to only send the map of key value pairs as a JSON for that particular locale to our web component.

Solution

Let’s say we support three language en, cn and jp language as of now. So we will have three files message_cn.properties message_jp.properties, message.properties in our resources folder. And we all know that we can access the message properties directly in thymeleaf templates as #{key_name} , but in our case we want all the key value pairs as a map at once. So let’s dive deep into how we solved it step by step.

Step 1

First, we will create a method to get all the message properties by accessing getMergedProperties method of ReloadableResourceBundleMessageSource class.

import java.util.Locale;import java.util.Properties;import org.springframework.context.support.ReloadableResourceBundleMessageSource;public class ExposedResourceMessageBundleSource extends ReloadableResourceBundleMessageSource {
public Properties getMessages(Locale locale) {
return getMergedProperties(locale).getProperties();
}
}

Step 2

Now, we can create a utility service which will send us the HashMap of key value pairs given the locale.

// Import ExposedResourceMessageBundleSourceimport org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;import org.springframework.context.MessageSource;import org.springframework.context.NoSuchMessageException;import org.springframework.stereotype.Service;@Service
public class MessageResolverService extends MessageSourceAware {
@Autowired
private MessageSource messageSource;
@Override
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
public Map<String, String> getMessages(Locale locale) {
Properties properties =((AnnotationConfigServletWebServerApplicationContext) messageSource)
.getBean("messageSource", ExposedResourceMessageBundleSource.class).getMessages(locale);
Map<String, String> messagesMap = new HashMap<>();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
messagesMap.put(entry.getKey().toString(), entry.getValue().toString());
}
return messagesMap;
}
}

Step 3 (Final)

Now we can inject MessageResolverService in our controller and convert it to JSON with the help of ObjectMapper. So we can create a utility method getLanguageMapJson which will call the getMessages method and write it as JSON using ObjectMapper and return the JSON string given the locale.

// Autowire MessageResolveService - import com.ti.dc.avl.service.MessageResolveService;// Autowire ObjectMapper - import com.fasterxml.jackson.databind.ObjectMapper;public String getLanguageMapJson(Locale locale) {
String languageJson = null;
try {
languageJson = objectMapper.
writeValueAsString(messageResolveService.
getMessages(locale));
} catch (Exception e) {
log.error("Something went wrong while converting HashMap to json" + e);
}
return languageJson;
}

--

--

Pratiyush Prakash

Full stack dev @ Texas Instruments. Follow me for short articles on software development. I will cover topics like Spring boot, Angular, SQL and so on.