无法绑定Thymeleaf中的复选框列表以获取修改后的数据

时间:2016-11-01 16:28:54

标签: java spring thymeleaf spring-web

我正在尝试为用户管理编写用户界面,其中一项重要的事情就是能够更改用户角色。

模型很简单,用户属于很多角色,角色有很多用户。

enter image description here

下面的代码展示了用于编辑现有用户的自包含@Controller:

@Controller
public class NewController {

    final Role r1 = new Role("admin");
    final Role r2 = new Role("user");
    final Role r3 = new Role("editor");

    final List<Role> allRoles = Arrays.asList(r1, r2, r3);

    final List<Role> userRoles = Arrays.asList(r3);

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editUser() {

        final User user = new User();
        user.setEmail("asdasdsa@email.com");
        user.setUsername("username");

        user.setAuthorities(userRoles);

        final ModelAndView mav = new ModelAndView("edit");

        allRoles.stream()
                .filter(r-> user.getAuthorities().contains(r))
                .forEach(r -> r.setChecked(true));

        mav.addObject("roles", allRoles);
        mav.addObject("user", user);
        return mav;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public ModelAndView updateUser(
            @ModelAttribute("user") User user,
            @ModelAttribute("roles") ArrayList<Role> roles,
            ModelMap model) {

        final List<Role> newRoles = roles.stream()
                .filter(r -> r.isChecked() != null)
                .filter(r -> r.isChecked() == true)
                .collect(Collectors.toList());

        user.setAuthorities(newRoles);

        return new ModelAndView("redirect:/edit");
    }
}

这是我的Spring-Thymeleaf页面,我可以编辑用户:

<form th:action="'/edit'" method="POST" enctype="utf8">

    <div class="form-group row">
        <label class="col-sm-3" th:text="#{label.user.id}">Id</label>
        <span class="col-sm-5" th:text="${user.id}">id</span>
    </div>

    <div class="form-group row">
        <label class="col-sm-3" th:text="#{label.user.username}">Username</label>
        <input class="form-control" name="username" th:value="${user.username}" required="required"/></span>
    </div>

    <div class="form-group row">
        <label class="col-sm-3" th:text="#{label.user.email}">email</label>
        <input type="email" class="form-control" name="email" th:value="${user.email}"
               required="required"/></span>
    </div>

    <div class="form-group row">
        <label class="col-sm-3" th:text="#{label.user.password}">password</label>
        <input id="password" class="form-control" name="password" value=""
               type="password"/></span>
    </div>

    <div class="form-group row">
        <label class="col-sm-3" th:text="#{label.user.confirmPass}">confirm</label>
        <input id="matchPassword" class="form-control" name="matchingPassword" value=""
               type="password"/></span>
    </div>

    <div th:each="item, index : ${roles}">
        <input type="checkbox"
               th:text="${item.authority}"
               name="${item.authority}"
               th:checked="${item.checked}" />
    </div>

    <button type="submit" class="btn btn-primary" th:text="#{label.edit.save}">save</button>
</form>

当我点击“保存”按钮时,会触发updateUser方法,但ArrayList roles为空。用户模型的其他值正确传递,我可以毫无问题地更改用户名/电子邮件/密码,正确填充用户bean。

1 个答案:

答案 0 :(得分:0)

好的,解决方法不同:

带有复选框处理的HTML页面片段应为:

<th:block th:each="role : ${roles}">
    <input type="checkbox"
           name="newRoles"
           th:checked="${role.checked}"
           th:value="${role.id}"/>
    <label th:text="${role.authority}"></label>
</th:block>

因此,当您提交表单时,您将获得newRoles RequestParam中的Role ID列表,这是我的POST控制器:

@RequestMapping(value = "/users/{id}/edit", method = RequestMethod.POST)
public ModelAndView updateUser(
        @ModelAttribute("user") User user,
        @RequestParam(value = "newRoles") ArrayList<Long> roles,
        BindingResult bindingResult , Model model) {

    final List<Role> newRoles =
            roles.stream()
                 .map(id -> roleService.findOne(id))
                 .collect(Collectors.toList());
    user.setAuthorities(newRoles);

    userService.update(user);

    return new ModelAndView("redirect:/users");
}