我正在尝试在grails中创建(我的第一个)taglib,除了我试图返回必须在表中显示的字符串列表/字符串数组之外,我有点不高兴了,但我得到的只是列表的第一个值。这是我得到的:

标签库:

def roles = { attrs, body ->
    def user = User.get(attrs.user)

    if(user) {
        def roles = Role.findAllById(UserRole.findByUser(user).roleId)
        def realRoles = []

        roles.each { role ->
            realRoles.add(role.authority.substring(5))
        }

        out << realRoles
        out << body()
    }
}

HTML:
<table class="table table-bordered table-hover" style="background-color: #FFFFFF;">
    <thead>
        <tr style="background-color: #007FB2;color: #FFFFFF;">
            <th>ID</th>
            <th>Name</th>
            <th>Surname</th>
            <th>Email</th>
            <th>Roles</th>
            <th>Delete</th>
        </tr>
    </thead>
    <g:each in="${users}" var="user">
        <tr>
            <td>${user.id}</td>
            <td>${user.firstName}</td>
            <td>${user.surname}</td>
            <td>${user.username}</td>
            <td><g:roles user="${user.id}" /></td>
            <td><button type="button" class="gen-btn btn-red" style="width: 100%;" onclick="confDelete(${user.id}, '${user.firstName}');">Delete</button></td>
        </tr>
    </g:each>

</table>

应该发生的事情是,当调用taglib时,应该去获取与用户ID关联的所有角色,然后获取每个角色的Authority属性,并从中删除前面的“ROLE_”。因此,ROLE_ADMIN变成了ADMIN,而ROLE_USER变成了USER等。我理想上想要的是一个可以在gsp中循环通过的列表,但是我意识到有很多问题要问,所以我是否可以得到以逗号分隔的列表角色的帮助从我的taglib回来,我真的很感激。

更明确地说,无论用户是否具有更多角色,我目前正在获得的字面都是[ROLE_ADMIN]。我想要的是角色的完整列表,例如ROLE_ADMIN, ROLE_MANAGER, ROLE_WHATEVER

提前致谢

编辑这是我的User,Role和UserRole域类。我正在使用Spring安全性生成这些类。

用户:
package fake.package.name

class User {

    transient springSecurityService

    String username
    String password
    String firstName
    String surname
    Date dateCreated
    boolean enabled
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    static constraints = {
        username blank: false, unique: true
        password blank: false
        firstName blank: false
        surname blank: false
    }

    static mapping = {
        password column: '`password`'
    }

    Set<Role> getAuthorities() {
        UserRole.findAllByUser(this).collect { it.role } as Set
    }

    def beforeInsert() {
        encodePassword()
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            encodePassword()
        }
    }

    protected void encodePassword() {
        password = springSecurityService.encodePassword(password)
    }

    String toString(){
        if((firstName)&&(surname))
            firstName+ " " +surname
        else
            username
    }
}

角色:
package fake.package.name

class Role {

    String authority

    static mapping = {
        cache true
    }

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

UserRole:
package fake.package.name

import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

    User user
    Role role

    boolean equals(other) {
        if (!(other instanceof UserRole)) {
            return false
        }

        other.user?.id == user?.id &&
                other.role?.id == role?.id
    }

    int hashCode() {
        def builder = new HashCodeBuilder()
        if (user) builder.append(user.id)
        if (role) builder.append(role.id)
        builder.toHashCode()
    }

    static UserRole get(long userId, long roleId) {
        find 'from UserRole where user.id=:userId and role.id=:roleId',
                [userId: userId, roleId: roleId]
    }

    static UserRole create(User user, Role role, boolean flush = false) {
        new UserRole(user: user, role: role).save(flush: flush, insert: true)
    }

    static boolean remove(User user, Role role, boolean flush = false) {
        UserRole instance = UserRole.findByUserAndRole(user, role)
        if (!instance) {
            return false
        }

        instance.delete(flush: flush)
        true
    }

    static void removeAll(User user) {
        executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
    }

    static void removeAll(Role role) {
        executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
    }

    static mapping = {
        id composite: ['role', 'user']
        version false
    }
}

请注意,因为这是一个工作项目,而不是个人项目,所以不允许在此处编辑代码。另外,我将软件包名称更改为fake.package.name,这不是软件包的实际名称。

最佳答案

我不知道您的User Role关联来自何处(Spring Security Framework?)还是由您自己编写的。而且您也没有给出域类的示例。

让我解释一下另一种解决方案:

如果您以某种方式设计域类,如下所示:

package xyz

class User {

    String name

    static hasMany = [authorities: Role]

    static constraints = {
    }
}

---------------

package xyz

class Role {

    static belongsTo = User

    String name

    static hasMany = [user: User]

    static constraints = {
    }
}

将创建第三个表“user_roles”以保存多对多关系/关联

使用此配置,您可以将您的taglib缩短为:
def roles = { attrs, body ->
    def user = User.get(attrs.user)

    if(user) {
        def realRoles = []
        user.authorities.each { r ->
            realRoles.add(r.authority.substring(5))
        }
        out << realRoles.join(', ')
        out << body()
    }
}

关于grails - 返回列表的Grails taglib,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39350276/

10-14 09:43
查看更多