2013-02-14 53 views
9

我有一个问题,当我使用双表单字段上的十进制分隔符使用圣杯自动数据绑定“前:测试t =新测试(params)”。经过几次搜索后,我发现它与浏览器语言环境有关。Grails数据绑定与十进制分隔符

例如: 如果输入小数点后用小数点'3.45'分隔的数字,则不起作用(数字的小数部分将被忽略)。它存储3.0在我的数据库

如果我做相同的测试,但使用逗号'3,45'小数点分隔符,一切工作正常。 Grails将3.45存储在数据库中。

问题是没有人用逗号分隔符输入数字。 (甚至数字小数点输入一个点'。'当设置为fr_CA时)

我已经发现了一些解决方案,如注册自定义数字编辑器(当你有很多应用程序时有点痛苦)或将全局localeResolver设置为en_US一个人没有做这项工作,因为我失去了我的应用程序的所有国际化功能)。

那么,有人有一个简单的解决方案来解决这个问题吗?

使用: 的Grails:2.2.0 浏览器:谷歌浏览器(区域fr_CA)

非常感谢!

回答

15

我一直在寻找并尝试2天。我终于选择定义一个自定义的PropertyEditorRegistar。这样,我可以修复仅适用于Double字段格式的区域设置。但是,我不认为这是最好的解决方案,因为它将应用于我的所有Double字段。但同时它做得很好。所以如果有人有更好的解决方案,我会很乐意测试它并更新我的代码。

所以这是我此设置:

1 - 创建一个实现PropertyEditorRegistrar的(如果你已经有一个,只需添加该方法所包含的代码的一部分在现有的一个)

新的Groovy类
import java.text.DecimalFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import org.springframework.beans.PropertyEditorRegistrar; 
import org.springframework.beans.PropertyEditorRegistry; 
import org.springframework.beans.propertyeditors.CustomNumberEditor; 

public class CustomDoubleRegistrar implements PropertyEditorRegistrar { 

    @Override 
    public void registerCustomEditors(PropertyEditorRegistry registry) { 
      //define new Double format with hardcoded Locale.ENGLISH 
     registry.registerCustomEditor(Double.class, 
       new CustomNumberEditor(Double.class, 
          DecimalFormat.getInstance(Locale.ENGLISH),true)) 
    } 

} 

2-定义自定义注册商到CONF /弹簧/ resources.goovy(如果它不是已存在当然)

beans = { 
    customPropertyEditorRegistrar(CustomDoubleRegistrar) 
} 

3-就是这样,在GRAI LS自动数据绑定将正常工作

Test t = new Test(params); 
//params contains many Double fields with dot '.' as decimal delimiter 

不要犹豫,发布更好的解决方案... 感谢

编辑1

因为Grails的2.3这个解决方案不再工作。如果你仍然想使用此解决方案,则必须将此配置添加到Config.groovy中文件

grails.databinding.useSpringBinder =真

或实现新DataBinding之一。我尝试了其中的几个,但似乎没有解决小数分隔符问题。谢谢你发布答案,如果你知道如何...

EDIT 2

由于2.4及以上的,你可以定义自己的ValueConverter的Grails绕过基本的语言环境验证。请注意,您必须删除在初始帖子和编辑1中所做的更改。以下是如何实现自定义ValueConverter:

的conf /春/ resources.groovy

// Place your Spring DSL code here 
beans = { 
    "defaultGrailsjava.lang.DoubleConverter"(DoubleValueConverter) 
} 

class DoubleValueConverter implements ValueConverter { 

    public LongValueConverter() { 
    } 

    boolean canConvert(value) { 
     value instanceof Double 
    } 

    def convert(value) { 
     //In my case returning the same value did the trick but you can define 
     //custom code that takes care about comma and point delimiter... 
     return value 
    } 

    Class<?> getTargetType() { 
     return Double.class 
    } 
} 
+2

它的工作原理! :), 非常感谢你! – conca 2013-05-09 23:32:25

+0

我正在使用grails 3.3.1,这个解决方案不适用于我的命令对象。也@BingUsing不工作。我不知道他们为什么改变旧的行为。新的一个令人厌恶:/ – pebbles 2017-12-08 14:23:43

0

我在这里有同样的问题。例如,德国的一个用户通常会输入一个(逗号)作为小数点分隔符,但显然您不能阻止他输入一个点;)如果您从Javascript中填充值,则获得本地化数字非常困难。所以我为控制器写了这个小帮手方法。它可能不包括所有可能的情况,但我需要它输入GPS坐标。随意提出改进建议。

/** 
    * Replaces , in the param with . an converts it to a Double. 
    * @param paramName an array of paramater names 
    */ 
    private convertDicimalParamsToDouble(paramName) { 
     paramName.each { it 
      def val = params[it] 
      if(val) { 
       val = val.replace(",", ".") 
       try { 
        params[it] = Double.parseDouble(val) 
       } catch (NumberFormatException) { 
        //ignore 
       } 
       log.debug("Converted decimal param ${it} with value '${params[it]}' to new value '${val}'") 
      } 
     } 
    } 

然后调用它像这样的例子:

def save() {   
    convertDicimalParamsToDouble(["lat", "lng"]) 
    ... 
相关问题