web-dev-qa-db-ja.com

フォルダ内に配置したときにMessageSourceのResourceBundleが見つかりません

Springのメッセージソースでリソースバンドルを使用しようとしています。ここに私がそれをしている方法があります:

@Component
public class MessageResolver implements MessageSourceAware {

    @Autowired
    private MessageSource messageSource;

    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    public String getMessage(){
        return messageSource.getMessage("user.welcome", new Object[]{"Rama"} , Locale.US);
    }

}

そして、これが私のフォルダ構造です:

enter image description here

messages_en_US.propertiesには、1行しか含まれていません。

user.welcome=Welcome {0}

使用されるxml構成は次のとおりです。

<bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename">
        <value>resourcebundles/messages</value>
    </property>
</bean>

ここに私が得ているエラーがあります:

WARNING: ResourceBundle [resourcebundles/messages] not found for MessageSource: Can't find bundle for base name resourcebundles/messages, locale en_US
Exception in thread "main" org.springframework.context.NoSuchMessageException: No message found under code 'user.welcome' for locale 'en_US'.

しかし、リソースバンドルをリソースフォルダーの直下に移動すると、問題なく動作します。この場合、使用しているxml構成は次のとおりです。

<bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
    <value>messages</value>
</property>

ResourceBundleMessageSourceを使用する必要がある場合、リソースバンドルをリソースの直下に配置する必要がありますか?指定したフォルダーのみに保持する必要がある場合、これを機能させる他の方法はありますか?

ありがとう!

10
Prasanth

XmlファイルのmessageSource Beanの構成を次のように変更します。

<bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 
    <property name="basename"> 
        <value>classpath*:resourcebundles/messages</value> 
    </property> 
</bean>

すべてのプロパティファイルはJavaのクラスパスにあるため、プレフィックスclasspath*:でパスを定義する必要があります。そうでない場合、アプリケーションのWebディレクトリを調べます。

これがお役に立てば幸いです。乾杯。

11
Japan Trivedi

たぶん、次のようにxml構成を変更できます。

使用する

org.springframework.context.support.ReloadableResourceBundleMessageSource

の代わりに

org.springframework.context.support.ResourceBundleMessageSource

このようなすべての構成:

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

もうすぐ2015年になり、Spring 4.1.2.RELEASEを使用していますが、messageSource Beanがターゲットリソースバンドルを取得するように構成する方法に間違いなく問題があります。

1)messageSource BeanがタイプReloadableResourceBundleMessageSourceの場合、機能しません。

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)messageSource BeanがタイプResourceBundleMessageSourceの場合、機能します。

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)構成クラスと組み合わせたXML構成ファイルを使用している場合-機能します(基本バンドルが修飾方法のようなクラスでどのように構成されているかに注意してください。つまり、「config/messages」ではなく「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>

そして:

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)最も重要なこと... WebApplicationInitializer(web.xmlなし)を使用している場合、「messageSource」Beanをルートコンテキストで定義する構成クラスを登録する必要があります。ディスパッチャーサーブレットのコンテキスト:

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");
    }
}
6
Tom Silverman

私の場合、Spring 4.3.2.RELEASEJava configおよびReloadableResourceBundleMessageSourceを使用して、テンプレートエンジンをBeanとして定義する必要がありました。私のメッセージは解決されませんでした。

これが動作する設定のサンプルです。

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;
}

}
2
Timothy Anyona

このためのYAMLバージョン

  spring:
     messages:
       basename: i18n/validation, i18n/message # for multiple properties just use comma separated values
       encoding: UTF-8

詳細については documentation を参照してください。

また、デフォルトのMessageSource BeanはResourceBundleMessageSourceであり、すでにクラスパスから読み取っているので、classpath:i18n/validationのような表記法を使用する必要はありません。

ディレクトリ構造

enter image description here

0
Edgar Asatryan
 <!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="resourcebundles/messages" />
</bean>

上記のようにメッセージパスを設定する必要があります。また、クラス名を確認してください。

0
Sachin J

私にとってうまくいったのは、本当にシンプルなものでした。

そうだった

<property name="basename">
            <value>locale\messages</value>
        </property>

に変更しました

<property name="basename">
            <value>locale/messages</value>
        </property>

\を変更するだけで修正されました。 MACを使用しています。

私は試していません*classpath、それは私にはうまくいかなかったかもしれません。

0
Siddharth

以下の設定を使用しましたが、私のプロジェクトでは問題なく機能しています。私のmessages.propertiesはパスの下にあります:..\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
Ganesh Teltia

次の設定を使用しましたが、正常に動作しています

<beans:bean id="messageSource class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <beans:property name="basename" value="classpath:resourcebundles/ScreenLabelResources" />
    </beans:bean>
0
Sanchi Girotra

以下の設定を使用しましたが、私のプロジェクトでは問題なく機能しています。

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

場所:src\main\resources\configurations\messages_en.properties

0