現在、単純な SpringMVC アプリケーションに取り組んでいます。最近、Spring-security を使い始めました。ユーザーとそれぞれのロールは、データベースに保持されます。私の現在のタスクは、「ユーザー登録」フォームを実装することです。シンプルな .jsp とスプリング フォームを使用しています。ユーザーは、ROLE_USER と ROLE_ADMIN の 2 つのロールを持つことができ、ROLE_USER はデフォルトでチェックされています。
これが私の AppUser および AppUserRoles モデルです。
AppUser.java :
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@Table(name="appusers")
public class AppUser {
@Id
@Column(name="USERNAME", unique = true, nullable = false, length = 45)
@NotEmpty(message="Username field cannot be empty")
private String username;
@Column(name="PASSWORD", nullable = false, length = 60)
@NotEmpty(message="Password field cannot be empty")
@Size(min=6,max=10,message="Password must be between 6 and 10 letters")
private String password;
@NotEmpty(message="The user must have at least one defined role")
@OneToMany(fetch = FetchType.LAZY, mappedBy = "appUser")
private Set<AppUserRole> userRole = new HashSet<AppUserRole>(0);
public AppUser() {
super();
}
public AppUser(String username, String password) {
super();
this.username = username;
this.password = password;
}
public AppUser(String username, String password, Set<AppUserRole> userRole) {
super();
this.username = username;
this.password = password;
this.userRole = userRole;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<AppUserRole> getUserRole() {
return userRole;
}
public void setUserRole(Set<AppUserRole> userRole) {
this.userRole = userRole;
}
}
AppUserRole.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="appuser_roles")
public class AppUserRole {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "USER_ROLE_ID", unique = true, nullable = false)
private Integer userRoleId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "username", nullable = false)
private AppUser appUser;
@Column(name = "ROLE", nullable = false, length = 45)
private String role;
public AppUserRole() {
super();
}
public AppUserRole(AppUser appuser, String role) {
super();
this.appUser = appuser;
this.role = role;
}
public Integer getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
public AppUser getAppuser() {
return appUser;
}
public void setAppuser(AppUser appuser) {
this.appUser = appuser;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
registerUser() メソッドを含む AppUserDAOImpl.java フラグメント:
@Override
public void registerUser(AppUser appUser) {
sessionFactory.getCurrentSession().persist(appUser);
logger.info(appUser.getUsername() + " persisted");
}
登録フォームに関連する UserController.java フラグメント:
@RequestMapping(value="/register")
public String goRegister(Model model) {
model.addAttribute("AppUser", new AppUser());
return "register";
}
@RequestMapping(value= "/registeruser_action", method = RequestMethod.POST)
public String addUser(@ModelAttribute("AppUser") @Valid AppUser appUser, BindingResult result){
if(result.hasErrors()){
return "register";
}
appUserDetailsService.registerUser(appUser);
return "redirect:/menu";
}
実際の形式の register.jsp フラグメント:
<sf:form commandName="AppUser" action="registeruser_action" method="POST" >
<div>
Username:<br>
<sf:input type="text" path="username"/>
<sf:errors path="username" cssClass="errors"/>
</div>
<div>
Password<br>
<sf:input type="text" path="password"/>
<sf:errors path="password" cssClass="errors"/>
</div>
<div>
User role:<br>
<sf:checkbox path="userRole" value="ROLE_USER"
disabled="true" checked="true" /> User <br>
<sf:checkbox path="userRole" value="ROLE_ADMIN"/> Admin <br>
<sf:errors path="userRole" cssClass="errors"/>
</div>
<br>
<input type="submit" value="Submit">
</sf:form>
具体的には、私がやりたいこと、インターネットで見つけたり見つけたりすることができないようです: チェックボックスの選択を AppUser.java モデルに設定された userRole に追加し、それらを永続化します。問題は、プロジェクトで以前にフォーム入力をオブジェクトフィールドにマップしたことがありますが、コレクションにはマップしたことがありません。私の楽観主義者は、チェックボックスをSpringフォームのuserRoleパスにマッピングするだけでそれができることをほとんど望んでいました.JavaとSpringは、それらをそのコレクションに追加する必要があることを「自動的に」理解するでしょう. 私の現実主義者は、それほど単純ではないことを知っています。正直なところ、私はそれがかなり些細なことだと知っていますが、解決策を見つけることができないようです. ここでその解決策を見つけたいと思っています。
PS: この質問にとって重要と思われるものだけを投稿しました。たとえば、サービス層は追加のように見えました。必要に応じて追加情報/コードを投稿します。
編集: OK、私は akshay の提案に従って、コンストラクターに ROLE_USER を追加しました。新しいユーザーを登録しようとしたときに発生した例外により、これは完全に間違っていることに気づきました。String を Set オブジェクトに割り当てようとしています。userRole は Set 型で、ROLE_USER は文字列です。このセットには、ユーザー名とそれぞれのロール文字列を含む AppUserRole オブジェクトが含まれています。基本的に、問題は次のとおりです。ユーザー名とそれぞれの役割を含む新しいオブジェクトを、スプリングフォームから userRole セットに直接追加するにはどうすればよいですか?