技术开发 频道

精通 Grails:用定制URI和codec优化Grails中的URI

  创建一个定制 codec

  在使用 User.login 而非 User.id 时,URI 很简单,因为它不包含空白。不错,目前尚没有任何的验证规则强制这种 “无空白” 的要求,但我们可以很轻松地添加一个这样的规则来强制 URI 遵从这一要求(参见 参考资料)。

  但是,若在 URI 内用 Entry.title 代替 Entry.id 又如何呢?标题几乎都要包含空白。一种解决方法是向 Entry 类内添加另一个字段并让终端用户重新输入没有空白的标题。这种做法不是很理想,因为它要求用户做更多的工作,而且还要求必须要编写另一个验证规则来确保用户能正确输入。更好的方法是让 Grails 根据使用 Entry.title 的位置自动将空白转变为下划线。要实现此目的,需要创建一个定制 codec(即 编码-解码器 的简写)。

  创建 grails-app/utils/UnderscoreCodec 并添加清单 10 所示代码:

  清单 10. 一个定制 codec

class UnderscoreCodec {
  static encode
= {target->
    target.replaceAll(
" ", "_")
  }
  
  static decode
= {target->
    target.replaceAll(
"_", " ")
  }
}

  Grails 提供了几个开箱即用的内置 codec:HtmlCodec、UrlCodec、Base64Codec 和 JavaScriptCodec(参见 参考资料)。HtmlCodec 是所生成的 GSP 文件内的 encodeAsHtml() 和 decodeHtml() 方法的源代码。

  您也可以向其中添加您自己的 codec。Grails 使用 grails-app/utils 目录内任何一个具有 Codec 后缀的类来将 encodeAs() 和 decode() 方法添加到 String。在本例中,Blogito 内的所有 String 都魔法般地具有了两个新方法:encodeAsUnderscore() 和 decodeUnderscore()。

  通过在 test/integration 内创建 UnderscoreCodecTests.groovy 可以验证这一点,如清单 11 所示:

  清单 11. 测试一个定制 codec

class UnderscoreCodecTests extends GroovyTestCase {
  void testEncode() {
    
String test = "this is a test"
    assertEquals
"this_is_a_test", test.encodeAsUnderscore()
  }
  
  void testDecode() {
    
String test = "this_is_a_test"
    assertEquals
"this is a test", test.decodeUnderscore()
  }
}

  在命令行提示符键入 grails test-app 运行测试。所看到的结果应该类似清单 12:

  清单 12. 测试成功运行后的输出

$ grails test-app
-------------------------------------------------------
Running
2 Integration Tests...
Running test UnderscoreCodecTests...
                    testEncode...SUCCESS
                    testDecode...SUCCESS
Integration Tests Completed in 157ms
-------------------------------------------------------
0
相关文章