我在互联网上看过很多例子,看起来解决方案应该可以正常工作。但仍然无法使我的代码工作。
用户:
@Entity
@Table(name = "users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
...
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "user_usertypes", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "usertype_id", referencedColumnName = "id"))
private Set<UserType> userTypes;
}
的用户类型:
@Entity
@Table(name = "usertypes")
public class UserType implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version
@Column(name = "version")
private Integer version;
@Column(name = "name")
private String name;
@ManyToMany(mappedBy = "userTypes")
private Set<User> users;
@Override
public int hashCode() {
int hash = 5;
hash = 83 * hash + Objects.hashCode(this.id);
return hash;
}
@Override
public boolean equals(Object obj) {
System.out.println("comparing objects");
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()){
return false;
}
final UserType other = (UserType) obj;
return Objects.equals(this.id, other.id);
}
}
用户控制器:
@Controller
public class UserController {
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String saveUser(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "users/userform";
}
System.out.println(user.getUserTypes());
userService.saveUser(user);
return "redirect:/user/" + user.getId();
}
@InitBinder
private void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(Set.class, "userTypes", new CustomCollectionEditor(Set.class) {
protected Object convertElement(Object element) {
if (element != null) {
System.out.println("From Controller: " + element.toString());
return userTypeService.findOne(Integer.parseInt(element.toString()));
}
return null;
}
});
}
用户窗体:
<form th:object="${user}" th:action="@{/user}" method="post">
<input type="hidden" th:field="*{id}"/>
<ul>
<li th:each="type : ${types}">
<input type="checkbox" th:id="${type.id}" th:field="*{userTypes}" th:value="${type.id}"/>
<label th:for="${type.id}" th:text="${type.name}">name</label>
</li>
</ul>
<form>
initBinder不会在提交时调用。仅在页面加载时。 所以,我的控制器无法获取userTypes对象。缺什么?谢谢!
答案 0 :(得分:0)
我找到了一个简单快捷的解决方案。可能不是最好的,但它按预期工作。希望,它会帮助别人。
用户实体:
private List<UserType> userTypes = new ArrayList<>();
在控制器中,我创建了一个帮助程序,为当前用户创建一个新的List以匹配表单上的索引:
public String edit(@PathVariable Integer id, Model model) {
model.addAttribute("user", updatedTypes(userService.getUserById(id)));
model.addAttribute("types", userTypeService.getAllUserTypes());
return "users/userform";
}
private User updatedTypes(User user) {
List<UserType> userTypes = new ArrayList<>();
for (long i = 0; i < userTypeService.count(); i++) {
userTypes.add(new UserType());
}
for (UserType type : user.getUserTypes()) {
userTypes.add(type.getId() - 1, type);
}
user.setTypes(userTypes);
return user;
}
<强>模板:强>
<li th:each="type, stat : ${types}">
<input type="checkbox" th:field="*{userTypes[__${stat.index}__]}"
th:value="${type.id}"/>
<label th:for="|userTypes${stat.index}|+1" th:text="${type.name}">
name
</label>
</li>
另外,我摆脱了initBinder方法。我不知道为什么,但它绝对没用。