我在我的Spring网络应用中启用了消息i18n。为此,我在servlet.xml
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages/message"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
添加上面的代码后,只要我在浏览器中点击我的应用程序,就会出现以下异常日志:
SEVERE: Servlet.service() for servlet [default] in context with path [/ERP-Web] threw exception [Filter execution threw an exception] with root cause
java.lang.StackOverflowError
at org.springframework.context.support.ReloadableResourceBundleMessageSource.getMergedProperties(ReloadableResourceBundleMessageSource.java:235)
at org.springframework.context.support.ReloadableResourceBundleMessageSource.resolveCodeWithoutArguments(ReloadableResourceBundleMessageSource.java:176)
at org.springframework.context.support.AbstractMessageSource.getMessageInternal(AbstractMessageSource.java:209)
at org.springframework.context.support.AbstractMessageSource.getMessageFromParent(AbstractMessageSource.java:257)
最后2行重复了100次并给了我StackoverflowException
。
当我使用ResourceBundleMessageSource
类时会发生完全相同的异常。
我的春季版本为4.3.6.RELEASE
。
以下是我的属性文件的内容
action.add.success = New {0} added successfully.
action.add.failure = Some error occurred in adding new {0}. Please try again later or contact administrator.
示例项目位于GitHub
答案 0 :(得分:1)
<强>更新强>
就我运行你的演示项目而言:
default-autowire="byType"
,它会将您的消息来源的父级设置为自身,从而导致堆栈溢出; LocaleContextHolder.getLocale()
,它在系统默认区域设置中继; ReloadableResourceBundleMessageSource
和ResourceBundleMessageSource
可以解决以下警告;
找不到MessageSource的ResourceBundle [messages / message]:无法找到基本名称消息/消息的包,locale en_US
<强> Runnable example 强>
就我从堆栈跟踪中看到的情况而言,您可能会遇到三个问题:
StackOverflow
(因为AbstractMessageSource
具有类似于类加载器的模型,即如果它无法解析则委托给父节点; StackOverflow
; 4.1.6 Relase
,我尝试过,工作正常; 答案 1 :(得分:1)
非常奇怪的情况; - )
基本问题是messageSource
自动连接到自身(在parentMessageSource
属性中)因为你使用default-autowire="byType"
这会导致未知消息代码的堆栈溢出异常混乱一切。必须说logback会给乱七八糟的东西带来麻烦,因为有时似乎异常发生在代码中,Log4J会更好地处理它。
Autowiring is not good for big projects,这是你的情况经典案例,但是如果必须使用它,请更改messageSource
bean添加以下内容:
<property name="parentMessageSource"><null/></property>
通过这种方式,您可以自己连接父级,并且不会发生自动装配。
这将恢复正常情况,其中未使用NoSuchMessageException
然后:
hello.world
消息,而不是message
messages/message.properties
简单来说,应用程序的默认语言环境就是您拥有所有消息的语言环境。从那开始,然后添加新语言(可能不完整)。 答案 2 :(得分:1)
我已在github中测试了您的示例代码,并且在运行时已显示所描述的错误,然后修改以下内容:
配置:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages/message"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
类别:
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public String getMessage() {
String msg = messageSource.getMessage("hello.world", null, LocaleContextHolder.getLocale());
return msg;
}
hello.word 是文件中包含名称 message_en.properties 的文字。
通过此修改,代码可以运行。
编辑未知消息代码:
我尝试使用未知的消息代码并且重复了错误,因此我查看了注册表,发现可能有多个具有相同名称的bean(潜在的循环引用< / strong>),但我没有发现为什么会发生这种情况,但是如果你需要工作,你必须像这样重命名bean。
<bean id="myMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages/message"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
然后使用:
@Autowired
private MessageSource myMessageSource;
但我认为这不能解决循环潜在错误的主要问题。
答案 3 :(得分:0)
您应该使用ResourceBundleMessageSource
的方式是设置basename
属性上的消息文件的路径。
例如,如果您有两个消息文件:
messages_en.properties
messages_es.properties
位于resources
文件夹。你的bean配置应该是这样的:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
其中messages
是两个文件名称的前缀。
也许抛出Exception
因为Spring id试图自动加载类路径,并且你也包含它,所以它试图反复加载它......
您可以在Mkyong's找到一个有效的例子。
答案 4 :(得分:0)
这在我的applicationContext.xml
文件中对我有用:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:i18n/message" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
请注意,我将属性文件放在以下路径中:
src/main/resources/i18n/message_en.properties