在下面的代码中,我只想创建一个新用户并将其链接到选定的组。
当用户和组有效时,一切正常。绑定结果有错误时会出现问题。控制器检测到这样的错误(到目前为止都很好)并返回相同的视图(我想保留用户输入的数据)但是组的列表是空的(我已经发现,在显示之后再次视图,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>
感谢任何帮助!
答案 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
您已完成。如果你不这样做,你的会话可能会污染。