在验证一节中,我们曾看到了Grails对错误信息的国际化支持,在本篇中,我们将彻底了解Grails国际化相关的内容,同时我们还将了解与安全相关的内容。
Grails对国际化的支持同样也是基于Locale和Message Bundle的。简单的说,Locale= language_code + country_code,如en_US或en_GB。Message Bundle的内容形式是:key=message。一个Message Bundle中的key都一样,而message则跟语言相关。Message Bundle的文件名构成:messages(_Locale).properties,在Grails中它们位于:grails-app/i18n。
缺省的Locale将由Request Header中的Accept-Language决定,如果你想动态切换,可以在查询字符串中添加:lang=locale,如/book/list?lang=es,在执行这个请求之后,Grails会把locale保存到cookie中,之后的请求可以不必再传。
至于消息的显示:
  • 无参数:<g:message code="my.localized.content" />
  • 有参数:<g:message code="my.localized.content" args="${['Juan', 'lunes']}" />
  • 在Controller和标签库中也可以使用:def msg = message(code:"my.localized.content", args:['Juan', 'lunes'])
在内容已知的情况下,使用Message Bundle可以非常简单地实现国际化。但是对于动态内容,使用数据库可能会更合适,如新闻网站中同一新闻的不同语言版本。在这种情况下,我们就必须自己获得Request的Locale,然后决定显示不同语言的版本。为了获得请求的Locale,可以:
def localeResolver = request.getAttribute(
    "org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER")
def locale = localeResolver.resolveLocale(request)
在知道locale之后,如何加载内容就简单了,在此就不再多言。
接下来,让我们看看Grails对安全方面提供哪些支持。Grails自动提供了:
  • 通过GORM域对象进行访问,自动转义SQL,防止SQL注入。
  • 缺省的脚手架模板自动进行HTML转义。
  • Grails的链接标签(link、form、createLink、createLinkTo等)为防止代码注入会自动转义。
  • Grails提供了codec,允许在产生HTML、JavaScript和URL等数据时进行细粒度的转义。
常见的安全问题及解决办法:
  • SQL注入:使用?参数占位符代替字符串拼接
  • 钓鱼(Phishing):对于这个问题,只能说是小心为上了。
  • 跨站脚本/HTML/URL注入:转义(codec),如encodeAsHTML、encodeAsURL。
  • DoS:负载均衡、限制数据流量。如果Grails产生的代码中会有:
    def safeMax = Math.max(params.max?.toInteger(), 100)
        return Book.list(max:safeMax)
  • 区分安全URL和公共URL,安全URL必须鉴权
Codec是Grails中的一个预置制品类型:
  • Grails会自动加载grails-app/utils下以Codec结尾的类
  • Codec类中包含encode和decode闭包
  • Grails会给Object类动态添加encodeAsX和decodeX方法,X为Codec的名字,如HTML:encodeAsHTML和decodeHTML
其中的encode和decode闭包并不要求同时出现,Grails会对此进行判断。Grails提供的标准Codec有:HTMLCodec、URLCodec、Base64Codec、JavaScriptCodec、HexCodec、MD5Codec、MD5BytesCodec、SHA1Codec、SHA1BytesCodec、SHA256Codec、SHA256BytesCodec。
自定义Codec例子:
class PigLatinCodec {
  static encode = { target ->
    // ……
  }
}
以上文件需要放在grails-app/utils下,使用:obj.encodeAsPigLatin()。
至于应用级别的安全,则分为:认证、鉴权和审计,即所谓的3A,这和其他框架下的内容并没有什么本质的不同。实现也大都是基于拦截器和过滤器实现。此外,对于流行的 ShiroSpring Security安全框架,Grails社区也都有了相应的插件。关于这方面的内容,请参见 GroovyLand 网站的 权限标签