ReloadableResourceBundleMessageSource с использованием подстановочного знака

После некоторых тестов оказалось, что ReloadableResourceBundleMessageSource не поддерживает подстановочные знаки.

Предположим, что файлы пакетов находятся в ресурсах и имеют следующие имена: messages.properties, messages_fr.properties и т. д.

Это базовое имя работает:

setBasename("classpath:/messages");

этот не

setBasename("classpath*:/messages*");

Итак, что я могу сделать, чтобы загрузить все файлы свойств, соответствующие заданному шаблону?

Примечание: мне нужно использовать эту реализацию ReloadableResourceBundleMessageSource, так как я хотел бы раскрыть все свойства данной локали на уровне REST... чтобы их можно было использовать с помощью перевода Angular на стороне клиента, как объяснено здесь.

Некоторые идеи? Большое спасибо.


person François Rosière    schedule 11.01.2016    source источник
comment
Почему? Правильный messages.properties загружается в зависимости от локали текущего пользователя. Итак, то, что вы пытаетесь сделать, уже сделано автоматически...   -  person M. Deinum    schedule 11.01.2016
comment
Необходимо использовать подстановочный знак, поскольку мое приложение является модульным, и в этих модулях определены несколько свойств messages.properties. На данный момент учитывается только один. Похоже, он загружается последним. Текущая реализация предполагает, что все свойства определены в одном файле.   -  person François Rosière    schedule 12.01.2016
comment
Вот как работает ResourceBundle.   -  person M. Deinum    schedule 12.01.2016
comment
Итак, просто для ясности, нельзя ли разделить свойства на несколько файлов, используя эту реализацию источника сообщений?   -  person François Rosière    schedule 12.01.2016


Ответы (1)


Как объясняется в этом post, метод refreshProperties ReloadableResourceBundleMessageSource может быть переопределен. чтобы разрешить загрузку нескольких ресурсов из пути к классам и соответствующих заданному шаблону

Давайте рассмотрим конкретный пример, используя большую часть Параметры весенней загрузки по умолчанию:

public class BaseReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource
    implements InitializingBean {

private static final String PROPERTIES_SUFFIX = ".properties";

private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

private final Charset encoding = Charset.forName("UTF-8");

@Autowired
private Environment environment;

/**
 * Returns the resource bundle corresponding to the given locale.
 */
public Properties getResourceBundle(Locale locale) {
    clearCacheIncludingAncestors();
    return getMergedProperties(locale).getProperties();
}

@Override
public void afterPropertiesSet() {
    setBasename("classpath*:/" + environment.getProperty("spring.messages.basename", "messages"));
    setDefaultEncoding(environment.getProperty("spring.messages.encoding", encoding.name()));
    setCacheSeconds(environment.getProperty("spring.messages.cache-seconds", int.class, -1));
    setFallbackToSystemLocale(environment.getProperty("spring.messages.fallback-to-system-locale",
            boolean.class, true));
}

@Override
protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
    final Properties properties = new Properties();
    long lastModified = -1;
    try {
        for (Resource resource : resolver.getResources(filename + PROPERTIES_SUFFIX)) {
            final PropertiesHolder holder = super.refreshProperties(cleanPath(resource), propHolder);
            properties.putAll(holder.getProperties());
            if (lastModified < resource.lastModified())
                lastModified = resource.lastModified();
        }
    } catch (IOException ignored) {
        // nothing to do
    }
    return new PropertiesHolder(properties, lastModified);
}

private String cleanPath(Resource resource) throws IOException {
    return resource.getURI().toString().replace(PROPERTIES_SUFFIX, "");
}

}

person François Rosière    schedule 12.01.2016