使用十进制分隔符的Grails数据绑定
当我使用grail自动数据绑定“ex:Test t=new Test(params)”和双表单字段上的十进制分隔符时,我遇到了一个问题。经过几次搜索,我发现它与浏览器的区域设置有关 例如: 如果我输入的数字以小数点“3.45”分隔,则不起作用(忽略数字的小数部分)。它在我的数据库中存储了3.0 如果我做同样的测试,但使用逗号'3,45'作为十进制分隔符,一切正常。Grails将3.45存储在数据库中 问题是没有人用逗号分隔符输入数字。(当设置为fr_CA时,即使是numpad也输入一个点“.”) 我已经找到了一些解决方案,比如注册自定义数字编辑器(当你有很多应用程序时有点痛苦)或者将全局LocalResolver设置为en_US(最后一个解决方案不起作用,因为我失去了应用程序的所有国际化功能) 那么,有没有人有一个简单的解决方案来解决这个问题 使用: Grails:2.2.0 浏览器:谷歌浏览器使用十进制分隔符的Grails数据绑定,grails,Grails,当我使用grail自动数据绑定“ex:Test t=new Test(params)”和双表单字段上的十进制分隔符时,我遇到了一个问题。经过几次搜索,我发现它与浏览器的区域设置有关 例如: 如果我输入的数字以小数点“3.45”分隔,则不起作用(忽略数字的小数部分)。它在我的数据库中存储了3.0 如果我做同样的测试,但使用逗号'3,45'作为十进制分隔符,一切正常。Grails将3.45存储在数据库中 问题是没有人用逗号分隔符输入数字。(当设置为fr_CA时,即使是numpad也输入一个点“.”)
非常感谢 我已经搜索和尝试了两天。我最终选择定义一个自定义属性YeditorRegistar。这样,我就可以修复双字段格式的区域设置。但是,我不认为这是最好的解决方案,因为它将应用于我所有的双字段。但与此同时,这项工作做得相当好。因此,如果有人有更好的解决方案,我会很高兴测试它并更新我的代码 我就是这样设置的: 1-创建一个实现PropertyEditorRegistrar的新groovy类(如果您已经有了一个,只需将该方法包含的部分代码添加到现有类中) 2-在conf/spring/resources.goovy中定义定制注册器(当然,如果它还没有出现的话) 3-就是这样,Grails自动数据绑定将很好地工作
Test t = new Test(params);
//params contains many Double fields with dot '.' as decimal delimiter
不要犹豫发布更好的解决方案。。。
谢谢
编辑1
由于Grails2.3,此解决方案不再有效。如果仍要使用此解决方案,则必须将此配置添加到Config.groovy文件中
grails.databinding.useSpringBinder=true
或者实现一个新的。我尝试了其中的一些,但似乎没有解决十进制定界符问题。谢谢你发布答案,如果你知道如何
编辑2
由于Grails2.4+版本,您可以定义自己的ValueConverter来绕过基本的语言环境验证。请注意,您必须删除在初始帖子和编辑1中所做的更改。以下是如何实现自定义ValueConverter:
conf/spring/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
}
}
//将您的Spring DSL代码放在这里
豆子={
“defaultGrailsjava.lang.DoubleConverter”(DoubleValueConverter)
}
类DoubleValueConverter实现ValueConverter{
公共价值转换器(){
}
布尔canConvert(值){
Double的值实例
}
def转换(值){
//在我的例子中,返回相同的值确实起了作用,但您可以定义
//关注逗号和点分隔符的自定义代码。。。
返回值
}
类getTargetType(){
返回双人舱
}
}
我这里也有同样的问题。例如,德国的用户通常会输入一个(逗号)作为十进制分隔符,但显然您不能阻止他输入点;)此外,如果从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"])
...
对于Grails2.3+,您可以正确地覆盖默认的活页夹/转换器,尽管它不是简单的或直观的
请参见我的回答:我正在使用grails 3.3.1,而此解决方案不适用于我的命令对象。另外,@bingsing也不起作用。我不知道他们为什么要改变旧的行为。新的一个很恶心:/
/**
* 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"])
...