Spring MVC:消息源似乎没有指向属性
Spring MVC: message source doesnt seem to point to the properties
我已经在这上面卡了好几天了。
这是我的 WebMvcConfig class:
package utils;
import Beans.Users;
import com.mycompany.fanalweb.backingbeans.Roles;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
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.annotation.ImportResource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
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.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
@ComponentScan({"com.mycompany.fanalweb.controllers", "com.mycompany.fanalweb.backingbeans", "utils", "Utils"})
@ImportResource({"classpath:SpringConfig.xml", "WEB-INF/webflow-config.xml", "WEB-INF/aop-config.xml"})
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public ViewResolver viewResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setCacheable(false);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".xhtml");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
ServletContextTemplateResolver flowResolver = new ServletContextTemplateResolver();
flowResolver.setCacheable(false);
flowResolver.setPrefix("/WEB-INF/flows/");
flowResolver.setSuffix(".xhtml");
flowResolver.setTemplateMode("HTML5");
flowResolver.setCharacterEncoding("UTF-8");
flowResolver.setOrder(0);
Set<TemplateResolver> set = new HashSet<>();
set.add(flowResolver);
set.add(templateResolver);
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolvers(set);
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setContentType("text/html; charset=UTF-8");
viewResolver.setOrder(1);
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
//session users and roles
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Users sessionUser() {
Users u = new Users();
return u;
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Roles sessionRoles() {
Roles u = new Roles();
return u;
}
//internationalization
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("/international/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
这是我的 WebAppInitializer:
package utils;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{
SecurityConfig.class,
WebMvcConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
应用程序启动良好,但在我的登录页面上,我的 "international texts" 没有翻译。
例如,我有:??user.mail_en?? , ??user.password_en??
我的属性文件位于:src/main/resources/international
它们被称为:messages.properties 和 messages_fr.properties
我已经试过了:
- 将它们放入 WEB-INF 但没有成功。
- 改变messageSource.setBasename("/international/messages");至 messageSource.setBasename("international/messages"); => 没有成功
除了 "international messages".
之外,没有显示任何错误并且页面呈现正确(图片,CSS,...)
谢谢你的帮助。
猜一猜:来自javadoc:
Note that the base names set as "basenames" property are treated in a
slightly different fashion than the "basenames" property of
ResourceBundleMessageSource. It follows the basic ResourceBundle rule
of not specifying file extension or language codes, but can refer to
any Spring resource location (instead of being restricted to classpath
resources). With a "classpath:" prefix, resources can still be loaded
from the classpath, but "cacheSeconds" values other than "-1" (caching
forever) will not work in this case.
所以也许只是尝试:classpath:/international/messages
如果您使用 ReloadableResourceBundleMessageSource
,则必须在您的基本名称前加上 classpath:
。所以在你的情况下:
classpath:/international/messages
解决方法如下:
Spring 4 with thymeleaf Internationalization not identify message from resource properties file
总结一下:您需要为viewResolver、templateResolver 和templateEngine 定义3 个不同的bean。您不能在 viewresolver 定义中定义 all。
似乎 Spring 需要 3 个不同的 bean 才能正常工作
我已经在这上面卡了好几天了。
这是我的 WebMvcConfig class:
package utils;
import Beans.Users;
import com.mycompany.fanalweb.backingbeans.Roles;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
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.annotation.ImportResource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
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.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
@ComponentScan({"com.mycompany.fanalweb.controllers", "com.mycompany.fanalweb.backingbeans", "utils", "Utils"})
@ImportResource({"classpath:SpringConfig.xml", "WEB-INF/webflow-config.xml", "WEB-INF/aop-config.xml"})
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public ViewResolver viewResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setCacheable(false);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".xhtml");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
ServletContextTemplateResolver flowResolver = new ServletContextTemplateResolver();
flowResolver.setCacheable(false);
flowResolver.setPrefix("/WEB-INF/flows/");
flowResolver.setSuffix(".xhtml");
flowResolver.setTemplateMode("HTML5");
flowResolver.setCharacterEncoding("UTF-8");
flowResolver.setOrder(0);
Set<TemplateResolver> set = new HashSet<>();
set.add(flowResolver);
set.add(templateResolver);
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolvers(set);
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setContentType("text/html; charset=UTF-8");
viewResolver.setOrder(1);
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
//session users and roles
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Users sessionUser() {
Users u = new Users();
return u;
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Roles sessionRoles() {
Roles u = new Roles();
return u;
}
//internationalization
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("/international/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
这是我的 WebAppInitializer:
package utils;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{
SecurityConfig.class,
WebMvcConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
应用程序启动良好,但在我的登录页面上,我的 "international texts" 没有翻译。 例如,我有:??user.mail_en?? , ??user.password_en??
我的属性文件位于:src/main/resources/international 它们被称为:messages.properties 和 messages_fr.properties
我已经试过了:
- 将它们放入 WEB-INF 但没有成功。
- 改变messageSource.setBasename("/international/messages");至 messageSource.setBasename("international/messages"); => 没有成功
除了 "international messages".
之外,没有显示任何错误并且页面呈现正确(图片,CSS,...)谢谢你的帮助。
猜一猜:来自javadoc:
Note that the base names set as "basenames" property are treated in a slightly different fashion than the "basenames" property of ResourceBundleMessageSource. It follows the basic ResourceBundle rule of not specifying file extension or language codes, but can refer to any Spring resource location (instead of being restricted to classpath resources). With a "classpath:" prefix, resources can still be loaded from the classpath, but "cacheSeconds" values other than "-1" (caching forever) will not work in this case.
所以也许只是尝试:classpath:/international/messages
如果您使用 ReloadableResourceBundleMessageSource
,则必须在您的基本名称前加上 classpath:
。所以在你的情况下:
classpath:/international/messages
解决方法如下:
Spring 4 with thymeleaf Internationalization not identify message from resource properties file
总结一下:您需要为viewResolver、templateResolver 和templateEngine 定义3 个不同的bean。您不能在 viewresolver 定义中定义 all。 似乎 Spring 需要 3 个不同的 bean 才能正常工作