ユーザー管理用の簡単な CRUD を作成しようとしています。したがって、2 つの基本的な Bean があります。
public class User {
private static final long serialVersionUID = 1L;
private Long userId;
private String login;
private String password;
private Set<Profile> profiles;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId= userId;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String pass) {
this.password = pass;
}
public Set<Profile> getProfiles() {
return profiles;
}
public void setPerfiles(Set<Profile> perfiles) {
this.profiles= profiles;
}
}
と
public class Profile{
private static final long serialVersionUID = 1L;
private Long profileId;
private String name;
public Profile() {
}
public Profile(String name) {
this.name= name;
}
public Long getProfileId() {
return this.profileId;
}
public void setProfileId(Long profileId) {
this.profileId= profileId;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name= name;
}
}
新しいユーザーを作成するには、モデル属性として機能するユーザーを使用してフォームを作成しました。
<f:form id="formCreateUser" action="${urlBase}users/saveUser"
method="post" modelAttribute="user">
<fieldset>
<div class="edit-form">
<f:label path="login">Login</f:label>
<f:input path="login" id="login" class="text ui-widget-content ui-corner-all" />
</div>
<div class="edit-form-multiple-select">
<label>Available profiles</label>
<select id="availableProfiles" multiple="multiple" class="ui-widget-content ui-corner-all" >
<c:forEach var="profile" items="${availableProfiles}" >
<option value="${profile.profileId}" ><s:message code="profile.${profile.name}"/></option>
</c:forEach>
</select>
</div>
<div class="edit-form-multiple-select-arrows" >
<a id="moveRight" href="#" class="form-button" style="display: inline-block; margin: 5px 0px; ">>></a>
<br>
<a id="moveLeft" href="#" class="form-button"><<</a>
</div>
<div class="edit-form-multiple-select">
<label>Actual profiles</label>
<f:select id="profiles" path="profiles" multiple="true" cssClass="ui-widget-content ui-corner-all">
<c:forEach var="profile" items="${user.profiles}" >
<f:option value="${profile.profileId}" ><s:message code="profile.${profile.name}"/></f:option>
</c:forEach>
</f:select>
</div>
</fieldset>
このフォームには 2 つの複数選択があります。
- ユーザーに追加できる利用可能なプロファイルを表示するもの (これらのプロファイルはデータベースから取得されます)
- すでにユーザーにバインドされている実際のプロファイルを表示する別のもの (これは新しいユーザーであるため、User オブジェクトのプロファイル セットは空です)
1 人のユーザーにいくつかのプロファイルを追加したい場合、オプションを availableProfiles 選択からプロファイル選択に移動します。
問題は、1 つまたは複数のプロファイルをある選択から別の選択に移動した後にフォームを送信すると、それらのプロファイルをコントローラーにマップできないことです。これはコントローラーメソッドです:
@RequestMapping("/saveUser")
public String saveUser(@ModelAttribute User user, BindingResult bindingResult, Model model, HttpServletRequest request){
try{
System.out.println(user.getProfiles()); // Here profiles are null
return "editUser";
}
catch(Exception e){
return "listUser";
}
}
PD: Formatter、CustomCollectionEditor、および PropertyEditor を使用して profileId を Set にバインドしようとしましたが、成功しませんでした。