2010-02-11 103 views
2

我想攔截對域類屬性的調用來實現訪問控制。Grails域類的屬性攔截

我的第一次嘗試是重寫setProperty和getProperty。通過這樣做,我禁用Grails領域類的所有好的功能,如

domainClass.properties = params 

和數據類型的自動轉換。

接下來的嘗試是使用DelegatingMetaClass,它使我至少能夠打印出實際調用周圍的一些漂亮的日誌消息。但我無法弄清楚如何訪問實際的對象來評估權限。

最後,groovy.lang.Interceptor似乎是一個不錯的選擇,因爲我可以訪問實際的對象。但這是正確的方式嗎?我如何能夠強制攔截所有域類?

非常感謝。

的問候,丹尼爾

回答

4

只要你引用真正的版本,您可以覆蓋的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