Grails域类的属性拦截

问题描述:

我想拦截对域类属性的调用来实现访问控制。Grails域类的属性拦截

我的第一次尝试是重写setProperty和getProperty。通过这样做,我禁用Grails领域类的所有好的功能,如

domainClass.properties = params 

和数据类型的自动转换。

接下来的尝试是使用DelegatingMetaClass,它使我至少能够打印出实际调用周围的一些漂亮的日志消息。但我无法弄清楚如何访问实际的对象来评估权限。

最后,groovy.lang.Interceptor似乎是一个不错的选择,因为我可以访问实际的对象。但这是正确的方式吗?我如何能够强制拦截所有域类?

非常感谢。

的问候,丹尼尔

只要你引用真正的版本,您可以覆盖的getProperty和setProperty。加入这样的代码来引导对添加拦截所有域类:

class BootStrap { 

    def grailsApplication 

    def init = { servletContext -> 

     for (dc in grailsApplication.domainClasses) { 
     dc.class.metaClass.getProperty = { String name -> 
      // do stuff before access 
      def result 
      def metaProperty = delegate.class.metaClass.getMetaProperty(name) 
      if (metaProperty) { 
       result = metaProperty.getProperty(delegate) 
      } 
      else { 
       throw new MissingPropertyException(name, delegate.class) 
      } 
      // do stuff after access 
      result 
     } 

     dc.class.metaClass.setProperty = { String name, value -> 
      // do stuff before update 
      def metaProperty = delegate.class.metaClass.getMetaProperty(name) 
      if (metaProperty) { 
       metaProperty.setProperty(delegate, value) 
      } 
      else { 
       throw new MissingPropertyException(name, delegate.class) 
      } 
      // do stuff after update 
     } 
     } 
    } 

    def destroy = {} 
} 
+0

你好, 非常感谢您的回复快。 你的代码确实帮了我很大忙。不幸的是,我看不到,如何在我的域类对象上调用方法。例如,我有一个名为A的域类,它提供了一个名为isReadable(String propertyName)的方法。那么如何在get或setProperty方法中调用这个函数呢?我可以通过delegate.metaClass.getMetaMethod(“isReadable”,java.lang.String)找到元方法,但调用总是会导致异常(java.lang.IllegalArgumentException:object不是声明类的实例)。 Regards,Daniel – Daniel 2010-02-11 20:28:35

+0

一种方法是用一个助手类的调用替换'do stuff before access'注释并在那里执行访问检查。类似于“PropertyChecker.isReadable(delegate.class,name)”,其中PropertyChecker.isReadable(Class clazz,String name)类似于“if(clazz == Person && name =='username'){...}”。此帮助程序也可以访问登录的用户以进行更细粒度的访问检查。 这会很快变得丑陋,所以你会想出一些简洁的方式来表示人们被允许改变或阅读什么时候。 – 2010-02-11 21:38:21

+0

感谢您的回复。但我不明白,为什么我不能在课堂上使用方法。我想,通过定义setProperty方法,该方法实际上被替换,就好像它是在域类本身中编写的一样。你的PropertyChecker例子表明,我不能使用实际的对象,而是使用一个类。不幸的是,这对我来说还不够,因为对象本身根据其状态来计算权限。有没有其他可能性如何拦截集合并获得财产电话?问候,丹尼尔 – Daniel 2010-02-12 09:41:19