2012-03-16 74 views
0

我正在使用spring-security-acl插件實現ACL安全性。我有以下域類:使用Grails安全ACL過濾選擇下拉菜單

package test 
class Subitem { 

    String name 

    static belongsTo = [employer: Employer] 

    static constraints = { 
    name blank: false 
    } 
} 

package test 
class Employer { 
    String name 

    static hasMany = [users: User, items: Subitem] 
    static belongsTo = User 

    static constraints = { 
    name blank: false, unique: true 
    } 

    String toString() { 
    name 
    } 
} 

在其用於創建一個子項的create.gsp文件中,有下面的語句:

<g:select id="employer" name="employer.id" from="${test.Employer.list()}" optionKey="id" required="" value="${subitemInstance?.employer?.id}" class="many-to-one"/> 

從EmployerController:

def list = { 
    params.max = Math.min(params.max ? params.int('max') : 10, 100) 
    [employerInstanceList: employerService.list(params), 
    employerInstanceTotal: employerService.count()] 
} 

按照給出的教程here,我已將一些與僱主打交道的功能轉移到名爲EmployerService的服務:

@PreAuthorize("hasRole('ROLE_USER')") 
@PostFilter("hasPermission(filterObject, read)") 
List<Employer> list(Map params) { 
    Employer.list params 
} 
int count() { 
    Employer.count() 
} 

使用ACL限制訪問任何給定僱主類實例中的信息。目前,我可以在下拉列表中看到數據庫中所有Employer實例,我假設這是因爲我使用的是控制器列表(),而不是服務列表() - 但是,我只想查看過濾列表的僱主領域類。但是,如果我更換G:選擇具有:

<g:select id="employer" name="employer.id" from="${test.EmployerService.list()}" optionKey="id" required="" value="${subitemInstance?.employer?.id}" class="many-to-one"/> 

然後我得到一個內部服務器錯誤,因爲我沒有通過一個地圖參數的服務列表()函數(我不知道如何標籤內),這樣做:

URI /security/subitem/create 
Class groovy.lang.MissingMethodException 
Message No signature of method: static test.EmployerService.list() is applicable for argument types:() values: [] Possible solutions: list(java.util.Map), is(java.lang.Object), wait(), find(), wait(long), get(long) 

我只希望看到來自EmployerService list()函數的信息 - 我怎麼做到這一點嗎?我如何從差距中引用正確的功能?

  • 編輯08年3月16日:謝謝@OverZealous,這真的很有幫助,我沒有意識到這一點。但是,我已經嘗試過,仍然遇到同樣的問題。我在Employer和EmployerService list()函數中都放了一個println()語句,並且可以看到,在解析g:select標籤時,實際上似乎都沒有調用過(即使我離開g:select來引用僱主)。是否有另一個版本的list()函數可能被調用?或者如何獲得g:select來考慮ACL?

回答

0

只要改變你的方法簽名的服務看起來像這樣:

List<Employer> list(Map params = [:]) { 
    Employer.list params 
} 

的變化是加入這樣的:= [:]。這爲params提供了默認值,在這種情況下,它是一個空映射。

(這是一個Groovy特性,順便說一句,你可以用它在任何方法或關閉這裏的參數是可選的,你要提供一個默認的。)

+0

非常感謝,我不知道!然而,似乎g:select調用list()函數的方式還有一個更深層次的問題 - 請參閱上面的編輯問題。 – John 2012-03-16 08:40:41

0

OK,我的工作了,在這裏是面對同樣問題的其他人的解決方案。

創建子項目頁面通過子項目的create.gsp文件和SubitemController呈現。關鍵是要修改SubitemController 創建()封閉:所以,現在當SubitemController通過G問

class SubitemController { 

def employerService 

def create() { 
    // this line was the default supplied method: 
    // [subitemInstance: new Subitem(params)] 
    // so replace with the following: 
    params.max = Math.min(params.max ? params.int('max') : 10, 100) 
    [subitemInstance: new Subitem(params), employerInstanceList: employerService.list(params), 
    employerInstanceTotal: employerService.count()] 
    } 
} 

:僱主列表中的子項視圖中選擇,它會調用EmployerService,這用品正確答案。我們簡單地添加了兩個返回到視圖的變量,並可以在視圖中的任何位置引用(例如,通過g:select標籤)。

對我來說,教訓是,視圖與控制器交互,控制器可以引用一個服務:看起來,該服務不能很好地與視圖一起玩。