Spring - BindingResult之后的模型属性有错误

时间:2015-01-16 07:30:07

标签: spring jsp model

在下面的代码中,我只想创建一个新用户并将其链接到选定的组。

当用户和组有效时,一切正常。绑定结果有错误时会出现问题。控制器检测到这样的错误(到目前为止都很好)并返回相同的视图(我想保留用户输入的数据)但是组的列表是空的(我已经发现,在显示之后再次视图,userform.groups为null)。

有没有人知道问题可能是什么?

用户窗体

@Component
public class UserForm {
    @Valid
    private User user;
    @Valid
    private Collection<Group> allGroups;

    // Setters and getters 
}

UserController中

@Controller
public class UserController {

    @Autowired
    UserGroupService userGroupService;

    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    @InitBinder
    public void initBinder (WebDataBinder binder) {
        binder.registerCustomEditor(Set.class, "userform.user.groups", new GroupListEditor(userGroupService));
    }

    @RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.GET)
    public ModelAndView createUsetGet () {

        ModelAndView mav = new ModelAndView("/admin/users/CreateUser");

        UserForm userForm = new UserForm();
        userForm.setUser(new User());
        userForm.setGroups(userGroupService.getAllEnabledGroups());
        mav.addObject("userform", userForm);

        return mav;
    }

    @RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.POST)
    public String createUserPost (@Valid @ModelAttribute("userform") UserForm userForm, BindingResult result) {

        if (result.hasErrors() == true) {
            return "/admin/users/CreateUser";
        }
        userForm.getUser().setPassword(passwordEncoder.encode(userForm.getUser().getPassword()));
        userGroupService.saveUser(userForm.getUser());

        return "redirect:/admin/users/ViewUsers";
    }
}

CreateUser.jsp (仅关于群组)

<form:form modelAttribute="userform" method="post">
    Username:
    <form:input path="user.loginName"/>

    <!-- More fields -->

    <form:select path="user.groups" multiple="true">
        <form:options items="${userform.groups}" itemValue="id" itemLabel="name" />
    </form:select>

    <button type="submit">Create</button>
</form:form>

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

这是因为重定向后有关验证错误的信息会丢失。 您可以使用RedirectAttributes解决此问题。查看this教程。

答案 1 :(得分:1)

重新创建对象,并将值绑定到结果对象。这意味着没有组对象。

那些根本不应该在对象中。要解决使用@ModelAttribute带注释的方法,将为每个请求处理方法调用该方法并创建一个对象并填充组列表。

@ModelAttribute
public void init(Model model) {
    UserForm userForm = new UserForm();
    userForm.setUser(new User());
    model.addAttribute("userform", userForm);
    model.addAtrribute("groups", userGroupService.getAllEnabledGroups());
}

@RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.GET)
public String createUsetGet () {
    return "/admin/users/CreateUser";
}

@RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.POST)
public String createUserPost (@Valid @ModelAttribute("userform") UserForm userForm, BindingResult result) {

    if (result.hasErrors() == true) {
        return "/admin/users/CreateUser";
    }
    userForm.getUser().setPassword(passwordEncoder.encode(userForm.getUser().getPassword()));
    userGroupService.saveUser(userForm.getUser());

    return "redirect:/admin/users/ViewUsers";
}

当然,你的jsp也必须稍微改变。

<form:select path="user.groups" multiple="true">
    <form:options items="${groups}" itemValue="id" itemLabel="name" />
</form:select>

使用此方法有一个缺点,现在为每个传入请求调用userGroupService.getAllEnabledGroups()。这可能不是必需的。您可以使用类上的@SessionAttributes注释将它们存储在会话中。

@Controller
@SessionAttributes("groups")
public class UserController {

    @Autowired
    UserGroupService userGroupService;

    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    @InitBinder
    public void initBinder (WebDataBinder binder) {
        binder.registerCustomEditor(Set.class, "userform.user.groups", new GroupListEditor(userGroupService));
    }

    @ModelAttribute("groups")
    public List<Group> groups() {
        return userGroupService.getAllEnabledGroups();
    }

    @ModelAttribute("userform")
    public UserForm userform() {
        UserForm userForm = new UserForm();
        userForm.setUser(new User());
        return userForm;
    }

    @RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.GET)
    public String createUsetGet () {
        return "/admin/users/CreateUser";
    }

    @RequestMapping(value = "/admin/users/CreateUser", method = RequestMethod.POST)
    public String createUserPost (@Valid @ModelAttribute("userform") UserForm userForm, BindingResult result, SessionStatus status) {

        if (result.hasErrors() == true) {
            return "/admin/users/CreateUser";
        }
        userForm.getUser().setPassword(passwordEncoder.encode(userForm.getUser().getPassword()));
        userGroupService.saveUser(userForm.getUser());
        status.setComplete();
        return "redirect:/admin/users/ViewUsers";
    }
}

成功之后,您需要告诉SessionStatus您已完成。如果你不这样做,你的会话可能会污染。