Spring 从对象中形成 select 枚举

Spring form select a enum from a object

我正在制作一个表单来编辑用户,每个用户都有多个角色(基于 Spring 安全性)。问题是 select 选项没有预 select 用户的通讯员角色。

用户

public class User implements UserDetails {
   ...
   private Set<UserRole> userRoles = new HashSet<>(0);
   ...
}

角色

public class UserRole implements GrantedAuthority {
   ...
   private Role role; //enum {ROLE_ADMIN, ROLE_USER,...}
   ...
}

表格

<form:fomr commandName="user">
   <form:input path="username" />
   ...
   <form:select multiple="true" path="userRoles" itemValue="role">
      <form:options items="${roles}"/>
   </form:select>
   ...
</form:form>

我确定问题出在 "userRoles",它是与 "roles" 不同类型的 Set。还有另一种制作表格的方法吗?

附言:items=${roles} == Roles.values()

已编辑:

User user = getUserById(id);
model.addAttribute("newUser", user);

@Transactional
public User getUserById(int id) {
    Session session = sessionFactory.getCurrentSession();
    User user = (User) session.get(User.class, id);
    if (user != null) {
        user.getUserRoles().size();
    }
    return user;
}

在您的 Role 枚举中有以下代码;

public enum Role {
    private static Map<Integer, String> idNameMap = new HashMap<Integer, String>();

    static {
        for(Role role:Role.values()) {
             idNameMap.put(role.ordinal(), role.name());
        }
    }

    public static Map<Integer, String> getIdNameMap() {
        return idNameMap;
    }
}

现在在你的控制器代码中而不是这样做

items=${roles} == Roles.values()

items=${roles} == Roles.getIdNameMap()

这应该可以很好地解决您的问题。

我有这个 "solution",但我一直在寻找 spring 自动执行的操作

        ...
        <form:select multiple="true" path="userRoles" itemValue="role">
            <c:forEach items="${roles}" var="role">
                <c:set var="selected" value="false" />
                <c:forEach items="${newUser.userRoles}" var="userRole">
                    <c:if test="${fn:containsIgnoreCase(userRole, role)}">
                        <form:option value="${role}" selected="true"/>
                        <c:set var="selected" value="true" />
                    </c:if>
                </c:forEach>
                <c:if test="${selected eq false}">
                    <form:option value="${role}"/>
                </c:if>
            </c:forEach>
        </form:select>
        ...