【问题标题】:Overriding Groovy's java.util.Date toString method覆盖 Groovy 的 java.util.Date toString 方法
【发布时间】:2015-08-28 18:34:00
【问题描述】:

我有一个 Grails(2.5.0 版;Groovy 2.4.3 版)应用程序,其中有一个 CustomPropertyEditorRegistry 可以在使用字段值时覆盖日期格式。

我安装了 ElasticSerach Grails 插件版本 0.0.4.4 ,安装后我注意到自定义属性编辑器不再工作。为了临时解决这个问题,我决定使用 Groovy 的元编程简单地覆盖 java.util.Date 的 toString() 方法。

我将此添加到 Bootstrap.groovy:

Date.metaClass.toString = {
   return delegate.format("MM/dd/yyyy HH:mm")
}

但是,当我进入 Grails 控制台时(使用 Grails 控制台插件):

new Date("Fri Jun 12 12:36:02 EDT 2015") as String == "Fri Jun 12 12:36:02 EDT 2015"
new Date("Fri Jun 12 12:36:02 EDT 2015").toString() == "06/12/2015 12:36"

println(new Date("Fri Jun 12 12:36:02 EDT 2015")) // prints Fri Jun 12 12:36:02 EDT 2015
println(new Date("Fri Jun 12 12:36:02 EDT 2015").toString()) // prints 06/12/2015 12:36 

任何解决自定义属性问题和/或覆盖 Date toString() 的帮助将不胜感激。我在 ElasticSearch Grails Plugin GitHub 上打开了一个问题,问题 #115 也是如此

编辑:

我使用 Grails 和 Groovy 进行了更多测试。

我在 Bootstrap.groovy 中使用此代码创建了一个新的 Grails 2.5.0 应用程序:

Date.metaClass.toString = {
    return delegate.format("MM/dd/yyyy HH:mm")
}

并将其添加到 index.gsp 视图中:

<ul>
    <li>new Date().toString() == ${new Date().toString()}</li>
    <li>new Date() == ${new Date()}</li>
    <li>new Date() as String == ${new Date() as String}</li>
</ul>

/*Output:
new Date().toString() == 06/15/2015 10:32
new Date() == Mon Jun 15 10:32:33 EDT 2015
new Date() as String == Mon Jun 15 10:32:33 EDT 2015
*/

我还使用以下代码/输出启动了带有 Groovy 版本 2.4.3 的 groovyConsole:

Date.metaClass.toString = {
    return delegate.format("MM/dd/yyyy HH:mm")
}

println(new Date())
println(new Date() as String)
println(new Date().toString())

/*Output:
06/15/2015 10:38
Mon Jun 15 10:38:12 EDT 2015
Mon Jun 15 10:38:12 EDT 2015
*/

所以这似乎是 Groovy 中的一个不一致之处,它没有从修改后的元类方法调用 toString(),除非我做错了什么或误解了什么。

【问题讨论】:

  • 我无法重现该行为。除非 Grails 在这里引起了某些事情,否则 as String 变体应该会导致 toString() 调用。然后当然具有相同的输出。所以我只能说 Groovy 本身并没有造成这种情况

标签: grails groovy elasticsearch


【解决方案1】:

您说您正在使用 Groovy 控制台,但您的意思是您正在运行 grails console,对吗? BootStrap 在启动控制台时不运行,仅在run-app 和测试中运行。如果您在控制台中运行 toString 覆盖,然后运行您的示例代码,它应该可以正常工作。

【讨论】:

  • 对不起,你是对的。我正在使用 Grails 控制台插件。所以 Bootstrap 应该已经运行了,对吗?
  • 是的,因为您正在访问正在运行的应用程序。
  • 因此,如果 as String 应该调用 .toString() ,这里似乎仍然有问题,但是打印这两个语句时的输出是不同的(更多详细信息请参见编辑)。
【解决方案2】:

关于“as String”的想法 ..如果你重新定义asType方法:

Date.metaClass.asType = { Class clazz ->
 return "Hello"
}

(new Date()) as String
===> Hello

但还是:

new Date()
===> Wed Jul 01 20:12:35 EEST 2015

【讨论】:

    【解决方案3】:

    由于我找不到覆盖有什么问题,而且它在单独打印实例时确实有效new Date(),我认为问题在于 Java 直接调用 toString() 方法,而不是让 Groovy 控制方法调用将导致执行 asType() 和 toString() 覆盖方法的过程。我不确定一个干净的解决方法,我仍然不确定为什么自定义属性编辑器在安装 ElasticSearch 插件时停止工作。

    【讨论】:

      猜你喜欢
      • 2018-01-10
      • 2018-07-05
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 2015-04-30
      • 2011-11-30
      • 2019-08-20
      相关资源
      最近更新 更多