Java Spring Boot中的消息本地化

Java Spring Boot中的消息本地化,java,spring,spring-boot,Java,Spring,Spring Boot,我有很多springboot应用程序。有许多模块,它们根据不同的情况以不同的方式组装。在其中,我有许多异常,其中一些对UI是可见的。这些例外情况应该本地化 基本上 spring-boot-fat-jar module-user.jar resources message.properties classes UserService.class UserCo

我有很多springboot应用程序。有许多模块,它们根据不同的情况以不同的方式组装。在其中,我有许多异常,其中一些对UI是可见的。这些例外情况应该本地化

基本上

 spring-boot-fat-jar
     module-user.jar
          resources
               message.properties
          classes
               UserService.class
               UserConflictException.class
     module-auth.jar
          resources
               message.properties
          classes
               NotAuthorizedException.class
我确实有一些特殊的例外情况(例如“您不能删除用户X,因为他们仍然被分配为组Y的经理”),这些例外情况很容易本地化-使用:

 throw new UserConflictException(
     msgSrc,
     "USER.DELETE.CONFLICT_HAS_GROUPS"
 );
这是可行的,因为消息所存储的属性文件和引发异常的代码(在本例中)位于相同的位置(即spring boot fat jar中的相同jar文件)

然而,如果我想抛出一个“NotAuthorizedException”,它基本上只是说“你没有被授权”。。。。然后该类可见,但消息不可见。显然,我不想在每个message.properties文件中重复该消息

相反,我希望累积类路径上的所有消息。所有消息代码都是分层/命名空间的,因此实际上没有冲突的风险

显然,我可以做一个类路径扫描,收集所有这些消息,然后从中实例化我自己的消息源。。。但这很可能不是正确的“春季战利品”方式。一定有更好的办法。你能帮我找到它吗?也许我只是错过了一些非常明显的东西


.rm

我有一个解决方案,目前还可以使用,只是有点难看-我实际上做了一个类路径扫描(使用快速类路径扫描程序)并将找到的消息添加到

ReloadableResourceBundleMessageSource 
像这样:

@Bean
public MessageSource globalMessageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    FastClasspathScanner fcs = new FastClasspathScanner();
    fcs.matchFilenamePattern("i18n/.*/messages\\.properties", new FileMatchContentsProcessor() {
        @Override
        public void processMatch(String relativePath, byte[] fileContents) throws IOException {
            try {
                relativePath = relativePath.substring(0, relativePath.length()-11);
                messageSource.addBasenames(relativePath);
                log.info("found messages: "+relativePath);
            } catch (Exception e2) {
                log.error("error processing mail template: "+relativePath,e2);
            }
        }
    });
    fcs.scan();
    return messageSource;
}
鉴于这些消息位于:

ressources/i18n/${module_name}

这就成功了。但是,我并不完全相信这是最好的解决方案。

属性文件的名称不应该相同。在相反的情况下,它只加载一个(首先在类路径上找到),您的意思是。。。如果我叫它们“${module\u name}\u messages.properties”,它能工作吗?如何声明消息源?我还尝试了“ApplicationContext.getResources(…”),但它从未找到所有文件。