使用Spring3的国际化下拉列表

使用Spring3的国际化下拉列表,spring,select,internationalization,Spring,Select,Internationalization,故事 我有一个代表用户访问级别的select控件。我正在寻找一种国际化的方法。标签应从消息资源中加载,值应按原样使用。我使用一个简单的SelectOption类在控制器中准备所有下拉列表,该类具有标签和值属性。这样,我的select看起来与所有jsp一致 问题 我发现了一些示例,但它们基于jsp中的逻辑。开发人员循环遍历他的标签,并使用消息资源手动构造选项标记。虽然这样做有效,但必须有更好的方法。我还发现一些评论说Spring3将支持国际化选项标签,但我找不到任何具体的内容 控制器逻辑 Coll

故事

我有一个代表用户访问级别的select控件。我正在寻找一种国际化的方法。标签应从消息资源中加载,值应按原样使用。我使用一个简单的SelectOption类在控制器中准备所有下拉列表,该类具有标签和值属性。这样,我的select看起来与所有jsp一致

问题

我发现了一些示例,但它们基于jsp中的逻辑。开发人员循环遍历他的标签,并使用消息资源手动构造选项标记。虽然这样做有效,但必须有更好的方法。我还发现一些评论说Spring3将支持国际化选项标签,但我找不到任何具体的内容

控制器逻辑

Collection<SelectOption> optionList = new ArrayList<SelectOption>();
optionList.add(new SelectOption("-SELECT-", "-"));  
optionList.add(new SelectOption("Administrator", "ADMIN"));
optionList.add(new SelectOption("Editor", "EDIT"));
bean.setFilterUserAccessLevelOptionList(optionList);
<form:select path="filterUserAccessLevel"  items="${bean.filterUserAccessLevelOptionList}" itemLabel="label" itemValue="value"/>

当我需要在jsp之外的控制器中执行这样的操作时,我已经让我的控制器具有MessageSourceAware。交换消息源时,Spring将注入一个新的消息源,您可以像Spring一样对其进行查询。在您的示例中,您将执行以下操作:

@Controller
public class someController implements MessageSourceAware {
    private MessageSource messageSource;

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

    @RequestMapping
    // Pass in the locale from the LocaleResolver
    public void someMapping(Locale locale){
        optionList.add(new SelectOption(
           messageSource.getMessage("userAccessLevelAdministratorLabel", null, locale),
           "ADMIN"))
    }
}

看一看SpringRoo项目。他们通过创建
tagx
标签来解决这类问题。此标记执行您已经描述的操作(它包含一个小逻辑,用于从Resources加载消息并构建选项标记)。但是,由于逻辑只需编写一次,而且您可以像在
jspx
文件中使用普通标记一样使用这些标记,因此它感觉像是一个做您想要的事情的标记。

我正在尝试您的想法。messageSource不知道我的消息包。我尝试使用一个与我的列表无关的条目,但使用spring:message显示的条目很好。相同的“无此类消息”错误。在调试器中,父消息源为空。而且,我找不到一种方法将区域设置注入到我的列表生成器中。将其作为参数传递是我连接各个部分的唯一方法。这可能是因为您的消息包没有添加到MessageSource中。查看可重新加载的ResourceBendleMessageSource或ResourceMessageBundleSource类。将其中一个实例化为bean,并使用消息包进行配置。另外,考虑制作组件MeaseService,这样,Spring上下文可以将它与一个新的上下文进行交换。这种映射之所以有效,是因为我的
尝试使用MessageSourceAware接口(请参阅我在这里的原始帖子中的代码)。Spring提供了在运行时更改MessageSource对象的功能,它使用该接口来更新任何直接询问它的人。我已经实现了该接口,并用我最新版本的列表生成器更新了帖子。我还是有例外。
messageSource
使用类型为
XmlWebApplicationContext
的对象设置。该对象有一个
configLocations
列表,其中有应用程序上下文和我的spring安全性的条目,但没有定义Message源代码的spring-servlet.xml条目。谢谢,Ralph。我的清单上有SpringRoo,但我试图一次解决一件事。我老了,需要慢慢来。:)@jacekn:只是想弄清楚我的意思:我不是说你应该使用ROO,我是说你应该创建一个ROO项目,看看他们是如何做tagx的(
input.tagx
),谢谢你的澄清,Ralph。实际上,我又开始读关于roo本身的书了。在正反两方面都有偏差。我知道你只是指标签。现在,我还在比赛,所以我会继续前进。但是坦率地说,我不喜欢我的java类获取依赖于语言的值这一事实。这是可行的,但对我来说,标签绝对是一个更好的地方来处理这个问题。当我在一个实际的项目中工作时,我肯定会发现tagx库。
@Component
public class SelectOptionListBuilderImpl implements SelectOptionListBuilder, MessageSourceAware {

private MessageSource messageSource;

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


@Override
public List<SelectOption> getUserAccessLevelOptionList(boolean addSelectPrompt, SortOrder sortOrder, Locale locale) {
    List<SelectOption> optionList = new ArrayList<SelectOption>();

    if(addSelectPrompt) {
        optionList.add(new SelectOption(messageSource.getMessage("common.selectPromptLabel", null, locale), "-"));
    }
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">    
<property name="basename" value="/WEB-INF/i18n/messages" />
<property name="defaultEncoding" value="UTF-8"/>
<property name="UseCodeAsDefaultMessage" value="true"/>
</bean>
org.springframework.context.NoSuchMessageException: No message found under code 'common.selectPromptLabel' for locale 'en_CA'
@Controller
public class someController implements MessageSourceAware {
    private MessageSource messageSource;

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

    @RequestMapping
    // Pass in the locale from the LocaleResolver
    public void someMapping(Locale locale){
        optionList.add(new SelectOption(
           messageSource.getMessage("userAccessLevelAdministratorLabel", null, locale),
           "ADMIN"))
    }
}