Grails 与语言环境无关的十进制数据绑定

Posted

技术标签:

【中文标题】Grails 与语言环境无关的十进制数据绑定【英文标题】:Grails locale-independent decimal databinding 【发布时间】:2015-12-17 11:03:57 【问题描述】:

什么问题:

在我的应用程序中,前端的数字始终以, 作为小数分隔符。当用户更改其语言环境并使用?lang=en_EN 参数编辑实体时,会出现错误绑定问题。发生的情况是,使用en_EN 语言环境,小数点分隔符是.,它在数据库中的输入11,001100 上产生价值,而不是11.00 - 涉及金钱的关键问题。

使用的软件:

Grails 2.3.8
Groovy 2.2.1

我想做的事:

在我的情况下,转换器中默认的“语言环境感知”方法非常有问题,我希望它们始终以相同的方式绑定,这应该是独立于语言环境的。

我已经尝试过的:

我发现默认情况下工作的原因是LocaleAwareNumberConverter,更具体地说是LocaleAwareBigDecimalConverter,所以我编写了一个简单的实现,它只使用一个语言环境(在本例中为GERMAN,因为它使用,作为小数分隔符)

@CompileStatic
class MyBigDecimalConverter extends LocaleAwareNumberConverter 

    @Override
    protected NumberFormat getNumberFormatter() 
        NumberFormat.getInstance(Locale.GERMAN)
    

包含在resources.groovy:

myBigDecimalConverter com.company.converters.MyBigDecimalConverter

但这只是行不通。值仍使用LocaleAwareBigDecimalConverter 进行转换。

编辑

我已将转换器更改为直接实现ValueConverter

@CompileStatic
class MyBigDecimalConverter implements ValueConverter 

    @Override
    boolean canConvert(Object value) 
        value instanceof String
    

    @Override
    Object convert(Object value) 
        def numberFormatter = NumberFormat.getInstance(Locale.GERMAN)
        numberFormatter.parse((String)value).asType(getTargetType())
    

    @Override
    Class<?> getTargetType() 
        BigDecimal
    

而且这个转换器也不会被调用。我对resources.groovy没有做任何更改

【问题讨论】:

我今天没有时间检查(不工作),但是这个类似的问题有一个值得研究的答案(如果你还没有看到它):***.com/questions/24274274/… 【参考方案1】:

好的,我想我现在可以正常工作了。它基于我的代码,但也应该适用于您。

要为BigDecimal 注册您自己的ValueConverter,您应该将defaultGrailsBigDecimalConverter(YourBigDecimalValueConverter) 添加到resources.groovy。我从 Grails 2.3.11 的 DataBindingGrailsPlugin.groovy 得出这个结论。

如果您在 Config.groovy 中有 grails.databinding.useSpringBinder = true,则需要删除它以启用 Grails 2.3 的新数据绑定。

我的ValueConverter 与您直接实现它的第二个示例相似,因此请先使用该示例以尽量减少可能发生的其他问题。

仅此而已。我已经实现了一个ValueConverter,它接受点和逗号作为分隔符,然后根据用户的语言环境显示它。它正在工作,棘手的部分是找出 resources.groovy 的正确名称,同时禁用 Spring binder。

【讨论】:

嗨!您是否有时间测试此解决方案并且您是否也让它为您工作? 是的,它成功了!所以留给我的唯一问题是用正确的名称连接它。那是defaultGrailsBigDecimalConverter。谢谢非常,非常感谢!恭喜你,赏金猎人,你中奖了! :-) 很高兴听到!这很有趣,但赏金实际上有所作为。这让我以不同的方式优先考虑我的任务,“现在就去做这个以获得奖金”:-) 很高兴知道我什么时候遇到困难!

以上是关于Grails 与语言环境无关的十进制数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

如何使日期与语言环境无关?

JVM理论:(三/1)class类文件结构

Android数据绑定上的字符串比较

模型绑定与验证笔记

Grails 命令对象数据绑定

虚拟机类加载机制