user4649752
user4649752

Reputation:

How to read all values from ResourceBundle into Map/InputStream Spring

I have an application that has the i18n feature enabled. So I have multiple files

messages.properties
messages_en.properties
messages_fr.properties

But for my frontend application I need to read all values at once, so they will be cached on the client side.

As a result I need to read all values for specific locale when a request is made.

I have tried MessageSource but it can return only a single entry, but I need to get all values in a form of Map or InputStream so they will be converted into JSON before returning to the clientside.

Please suggest a way I can read all values for a specific Properties bundle for a specific location.

Thanks

Upvotes: 2

Views: 2915

Answers (1)

user6365858
user6365858

Reputation:

Define the following class:

import java.util.*;
import java.util.stream.Collectors;

public class MessagesResourceBundle {
    private static final String BASE_NAME = "messages";
    private static final List<String> LOCALES = Arrays.asList("en", "fr");
    private Map<Locale, Map<String, String>> allMessages;

    public MessagesResourceBundle() {
        allMessages = new HashMap<>();
        List<Locale> locales = LOCALES.stream().map(Locale::new).collect(Collectors.toList());
        locales.add(Locale.ROOT);
        locales.stream().map(l -> ResourceBundle.getBundle(BASE_NAME, l))
                .forEach(bundle -> {
                    Map<String, String> messages = new HashMap<>();
                    Collections.list(bundle.getKeys()).forEach(key -> messages.put(key, bundle.getString(key)));
                    allMessages.put(bundle.getLocale(), messages);
                });
    }

    public Map<Locale, Map<String, String>> getAllMessages() {
        return Collections.unmodifiableMap(allMessages);
    }
}

Then in your @SpringBootApplication class (or in a @Configuration annotated class), define the following method:

@Bean
public MessagesResourceBundle messagesResourceBundle() {
    return new MessagesResourceBundle();
}

You can then inject it in the class you want to use it.

Upvotes: 2

Related Questions