我正在尝试使用Spring的Message Source资源包。这是我的方式:
@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);
}
}
这是我的文件夹结构:
messages_en_US.properties只包含一行:
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,我应该将我的资源包直接放在资源下吗?如果我必须将它保留在指定的文件夹中,还有其他方法可以使这个工作吗?
谢谢!
答案 0 :(得分:17)
男孩,也许您可以按如下方式更改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>
答案 1 :(得分:11)
将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目录。
希望这会对你有所帮助。欢呼声。
答案 2 :(得分:6)
现在差不多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配置文件 - 它将起作用(注意基本包如何在类中配置,例如资格认证方式,即&#39; config.messages&#39;不是&#39; config / messages&#39;):( 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),您必须注册定义&#39的配置类;为messageSource&#39; bean在根上下文中,而不是在调度程序servlet的上下文中:
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");
}
}
答案 3 :(得分:2)
就我而言,使用Spring 4.3.2.RELEASE 和 java 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;
}
}
答案 4 :(得分:1)
是,如果我必须使用ResourceBundleMessageSource,我应该把 我的资源捆绑在资源的正下方?如果我必须保留它 仅在指定的文件夹中,还有其他方法可以完成这项工作吗?
您可以在自己的程序包中定义您的消息,它不需要位于资源文件夹中。
使用Spring 5.2.2.RELEASE版本化的组件,这是我设法使其工作的方式:
文件的限定名称为:
/tutproject/src/com/tutproject/app/messages/messages.properties
在我的Spring Bean配置文件(XML)中,bean的定义如下:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"
value="/com/tutproject/app/messages/messages">
</property>
</bean>
Java构建路径包括tutproject/src
,这是XML定义中省略的位置的一部分。
ResourceBundleMessageSource类中的一些其他有用信息:
基本名称遵循{@link java.util.ResourceBundle} 约定:本质上,*完全合格的类路径位置。如果 它不包含包限定符*(例如{@code org.mypackage}),它将从类路径根目录解析。 * 注意 JDK的标准ResourceBundle将点视为包 分隔符:* 这意味着“ test.theme”实际上等效 来“测试/主题” 。
答案 5 :(得分:0)
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="resourcebundles/messages" />
</bean>
您必须如上所示配置邮件路径。 另外,检查班级名称。
答案 6 :(得分:0)
我使用了以下配置并且工作正常
<beans:bean id="messageSource class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:resourcebundles/ScreenLabelResources" />
</beans:bean>
答案 7 :(得分:0)
对我有用的东西非常简单。
是
<property name="basename">
<value>locale\messages</value>
</property>
我把它改成了
<property name="basename">
<value>locale/messages</value>
</property>
只是一个\来/更改为我修复它。我正在使用MAC。
我没有尝试*classpath
,这可能对我不起作用。
答案 8 :(得分:0)
我使用了以下配置,它在我的项目中运行正常。 我的messages.properties位于以下路径中: .. \的WebContent \ WEB-INF \资源
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:WEB-INF/resources/messages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
答案 9 :(得分:0)
我使用了以下配置,并且在我的项目中运行正常。
declare
位置:cg$rec_its cg$scm_inventory_trans.cg$row_type;
答案 10 :(得分:0)
为此的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
这样使用非符号。
答案 11 :(得分:0)
在Spring Boot 2.2.5中,情况有所变化。不再需要Classpath。
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
答案 12 :(得分:0)
我强烈建议将属性文件保留在项目之外,这样我们就不必为每次属性更改都编译代码。
在实时项目中使用以下配置。在application.properties文件中设置property.location值
@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;
}
}