ResourceBundle not found for MessageSource when placed inside a folder

后端 未结 13 1258
星月不相逢
星月不相逢 2020-12-08 17:11

I am trying to use resource bundles with Spring\'s Message Source. Here is the way I am doing it:

@Component
public class MessageResolver implements MessageS         


        
相关标签:
13条回答
  • 2020-12-08 17:47

    I strongly suggest to keep property files out side of project so that we don't need to compile code for every property change.

    Below configuration we are using in live project. setting property.location value in application.properties file

    @Configuration
    public class LocalizationConfiguration {
    
        private static final Logger logger = LoggerFactory.getLogger(LocalizationConfiguration.class);
    
        @Value("${property.location}")
        private String propertyLocation;
    
        @Bean
        public LocaleResolver localeResolver() {
            SessionLocaleResolver localeResolver = new SessionLocaleResolver();
            localeResolver.setDefaultLocale(Locale.ENGLISH); // change this
            return localeResolver;
        }
    
        @Bean
        public ReloadableResourceBundleMessageSource messageSource() {
            ReloadableResourceBundleMessageSource  resource = new ReloadableResourceBundleMessageSource();
            String messageFolderPath = propertyLocation + "/" + "i18n";
            resource.setBasename("file:"+messageFolderPath+"/messages");
            resource.setDefaultEncoding("UTF-8");
            resource.setCacheSeconds(10);
            return resource;
        }
    
        @Bean
        public LocalValidatorFactoryBean validatorFactoryBean() {
            LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
            bean.setValidationMessageSource(messageSource());
            return bean;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 17:50

    I have used following configuration and it is working fine in my project. My messages.properties is in below path: ..\WebContent\WEB-INF\resources

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:WEB-INF/resources/messages" />
        <property name="useCodeAsDefaultMessage" value="true" />
    </bean>
    
    0 讨论(0)
  • 2020-12-08 17:50

    I have used following configuration and it is working fine in my project.

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:configurations/messages" />
        <property name="useCodeAsDefaultMessage" value="true" />
    </bean>
    

    location: src\main\resources\configurations\messages_en.properties

    0 讨论(0)
  • 2020-12-08 17:51

    It's nearly 2015 now and I'm using Spring 4.1.2.RELEASE and there's definitely a problem with the way the messageSource bean needs to be configured so it picks up the target resource bundle.

    1) If the messageSource bean is of type ReloadableResourceBundleMessageSource it won't work:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    
    @Configuration
    @ComponentScan(basePackages = { "com.intertech.service" })
    //@ImportResource({"classpath:spring/applicationContext-i18n.xml"})
    public class AppConfig {
    
      @Bean(name = "messageSource")
      public ReloadableResourceBundleMessageSource getMessageSource() {
          ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
          messageSource.setBasename("config/messages");
          messageSource.setDefaultEncoding("UTF-8");
          messageSource.setUseCodeAsDefaultMessage(true);
          return messageSource;
      }
    
    //  @Bean(name = "messageSource")
    //  public ResourceBundleMessageSource getMessageSource() {
    //      ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    //      messageSource.setBasename("config/messages");
    //      messageSource.setDefaultEncoding("UTF-8");
    //      messageSource.setUseCodeAsDefaultMessage(true);
    //      return messageSource;
    //  }
    }
    

    2) If the messageSource bean is of type ResourceBundleMessageSource it will work:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ResourceBundleMessageSource;
    
    @Configuration
    @ComponentScan(basePackages = { "com.intertech.service" })
    //@ImportResource({"classpath:spring/applicationContext-i18n.xml"})
    public class AppConfig {
    
    //  @Bean(name = "messageSource")
    //  public ReloadableResourceBundleMessageSource getMessageSource() {
    //      ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    //      messageSource.setBasename("config/messages");
    //      messageSource.setDefaultEncoding("UTF-8");
    //      messageSource.setUseCodeAsDefaultMessage(true);
    //      return messageSource;
    //  }
    
      @Bean(name = "messageSource")
      public ResourceBundleMessageSource getMessageSource() {
          ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
          messageSource.setBasename("config/messages");
          messageSource.setDefaultEncoding("UTF-8");
          messageSource.setUseCodeAsDefaultMessage(true);
          return messageSource;
      }
    }
    

    3) If you're using an XML configuration file combined with a configuration class - it will work (notice how the base bundle is configured in a class like qualification manner i.e. 'config.messages' not 'config/messages'): (applicationContext-i18n.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource"
            p:basename="config.messages"
            p:useCodeAsDefaultMessage="true"/>
    
        <!-- This will not work -->
        <!--
        <bean id="messageSource"
            class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
            p:basename="config/messages"
            p:useCodeAsDefaultMessage="true"/>
         -->
    </beans>
    

    and:

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    @Configuration
    @ComponentScan(basePackages = { "com.intertech.service" })
    @ImportResource({"classpath:spring/applicationContext-i18n.xml"})
    public class AppConfig {
    
    //  @Bean(name = "messageSource")
    //  public ReloadableResourceBundleMessageSource getMessageSource() {
    //      ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    //      messageSource.setBasename("config/messages");
    //      messageSource.setDefaultEncoding("UTF-8");
    //      messageSource.setUseCodeAsDefaultMessage(true);
    //      return messageSource;
    //  }
    
    //  @Bean(name = "messageSource")
    //  public ResourceBundleMessageSource getMessageSource() {
    //      ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    //      messageSource.setBasename("config/messages");
    //      messageSource.setDefaultEncoding("UTF-8");
    //      messageSource.setUseCodeAsDefaultMessage(true);
    //      return messageSource;
    //  }
    }
    

    4) Most importantly... if you're using a WebApplicationInitializer (no web.xml), you've got to register the configuration class that defines the 'messageSource' bean in the root context, not in the dispatcher servlet's context:

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRegistration;
    
    import org.springframework.web.WebApplicationInitializer;
    import org.springframework.web.context.ContextLoaderListener;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.DispatcherServlet;
    
    public class WebAppInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext container) throws ServletException {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);
        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(MvcConfig.class);
        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(
                dispatcherServlet));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("*.htm");
        }
    }
    
    0 讨论(0)
  • 2020-12-08 17:53

    I have used following configuration and it is working fine

    <beans:bean id="messageSource class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
            <beans:property name="basename" value="classpath:resourcebundles/ScreenLabelResources" />
        </beans:bean>
    
    0 讨论(0)
  • 2020-12-08 17:55

    In my case, using Spring 4.3.2.RELEASE and java config and a ReloadableResourceBundleMessageSource, I had to define my template engine as a bean otherwise my messages were not getting resolved.

    Here's a sample of a working configuration.

    AppConfig.java

    import java.util.concurrent.TimeUnit;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.context.MessageSource;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.spring4.SpringTemplateEngine;
    import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
    import org.thymeleaf.spring4.view.ThymeleafViewResolver;
    import org.thymeleaf.templatemode.TemplateMode;
    import org.thymeleaf.templateresolver.ITemplateResolver;
    
    @Configuration
    @EnableWebMvc
    @ComponentScan("myapp")
    public class AppConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
    
    private ApplicationContext applicationContext;
    
    private static final boolean CACHE_THYMELEAF_TEMPLATES = false;
    private final String UTF8_ENCODING = "UTF-8";
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    
    @Bean
    public ViewResolver viewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        resolver.setCharacterEncoding(UTF8_ENCODING);
        resolver.setCache(CACHE_THYMELEAF_TEMPLATES);
        return resolver;
    }
    
    @Bean
    public TemplateEngine templateEngine() {
        //this method must be defined as a bean otherwise i18n messages are not found
        //if method defined as private TemplateEngine templateEngine() messages are not found
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setEnableSpringELCompiler(true);
        engine.addTemplateResolver(templateResolver());
        return engine;
    }
    
    private ITemplateResolver templateResolver() {
        SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setApplicationContext(applicationContext);
        resolver.setPrefix("/WEB-INF/thymeleaf/");
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setSuffix(".html");
        resolver.setCacheable(CACHE_THYMELEAF_TEMPLATES);
        resolver.setCharacterEncoding(UTF8_ENCODING);
        return resolver;
    }   
    
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("WEB-INF/i18n/messages");
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setDefaultEncoding(UTF8_ENCODING);
        messageSource.setFallbackToSystemLocale(false);
        messageSource.setCacheSeconds((int)TimeUnit.HOURS.toSeconds(1));
        return messageSource;
    }
    
    }
    
    0 讨论(0)
提交回复
热议问题