2011-08-08 15 views
5

最初の小さな背景情報。ユーザーが多くの役割を果たすことができる、かなり標準的なユーザー役割の関係を得ました。私は、ユーザークラス内のセットとして定義されたロールを持っています。今私は、HTMLフォームは文字列としてすべての値を持っていると私のカスタムロールオブジェクトとして機能しない値を取得しようとしていることを知っている。私はinitbinderを実装してidをオブジェクトに変換して、選択した値をチェックボックスから取り出すことができるようにしました。Spring MVC事前投入チェックボックス

しかし、私は逆に戻ることはできません。私はすでにロールを持っているデータベースから、ユーザーが持つすべてのロールでロールチェックボックスをあらかじめ設定したいユーザーを取得します。この例に基づいて:

Checkboxes example

彼らは言う:

形:チェックボックス項目= "$ {ダイナミックリスト}" パス= "プロパティ・ツー・ストア"

複数のチェックボックスの場合、「パス」または「プロパティ」の値が で「チェックボックスの値 - $ {ダイナミックリスト}」のいずれかと同じであれば、一致した チェックボックスが自動的にチェックされます。

私の解釈では、すべてのロールのセットをフィードし、Userオブジェクトからのロールになるパスを定義する必要があります。したがって、一致する必要があり、チェックボックスがあらかじめ設定されている必要があります。

すべての例では、dynamic-listの値がString []となっているようです。うーん、それは素晴らしいとダンディーが、私たちはセットとして定義されているカスタムオブジェクトのためにこれはどのように機能しますか?この1行の定義をチェックボックスに使用することはできますか?また、何らかの種類のデータバインディングの見出しをビューに追加する必要がありますか?

私のユーザdto、ユーザコントローラ、カスタムフォームバインダ、およびユーザ編集ページがここにあります。

ユーザーDTO

@Entity 
@Table 
public class User extends BaseDto 
{ 
    @Column(updatable = false) @NotBlank 
    private String username; 

    @Column(name = "encrypted_password") @Size(min = 6, message = "password must be at least 6 characters") @Pattern(regexp = "^\\S*$", message = "invalid character detected") 
    private String password; 

    @Column(name = "first_name") 
    private String firstName; 

    @Column(name = "last_name") 
    private String lastName; 

    @Column @NotNull 
    private boolean enabled; 

    @Column @Email @NotBlank 
    private String email; 

    @Transient 
    private String confirmPassword; 

    @ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER, cascade = CascadeType.REFRESH) @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), 
     inverseJoinColumns = @JoinColumn(name = "role_id")) 
    private Set<Role> roles; 

    public User() 
    { 
    } 

    public User(final String usernameIn, final String passwordIn, final String firstNameIn, final String lastNameIn, final String emailIn, final boolean enabledIn) 
    { 
     username = usernameIn; 
     password = passwordIn; 
     firstName = firstNameIn; 
     lastName = lastNameIn; 
     email = emailIn; 
     enabled = enabledIn; 
    } 

    public String getUsername() 
    { 
     return username; 
    } 

    public void setUsername(final String usernameIn) 
    { 
     username = usernameIn; 
    } 

    public String getPassword() 
    { 
     return password; 
    } 

    public void setPassword(final String passwordIn) 
    { 
     password = passwordIn; 
    } 

    public String getFirstName() 
    { 
     return firstName; 
    } 

    public void setFirstName(final String firstNameIn) 
    { 
     firstName = firstNameIn; 
    } 

    public String getLastName() 
    { 
     return lastName; 
    } 

    public void setLastName(final String lastNameIn) 
    { 
     lastName = lastNameIn; 
    } 

    public String getEmail() 
    { 
     return email; 
    } 

    public void setEmail(final String emailIn) 
    { 
     email = emailIn; 
    } 

    public String getConfirmPassword() 
    { 
     return confirmPassword; 
    } 

    public void setConfirmPassword(final String confirmPasswordIn) 
    { 
     confirmPassword = confirmPasswordIn; 
    } 

    public boolean isEnabled() 
    { 
     return enabled; 
    } 

    public void setEnabled(final boolean enabledIn) 
    { 
     enabled = enabledIn; 
    } 

    public Set<Role> getRoles() 
    { 
     return roles; 
    } 

    public void setRoles(final Set<Role> rolesIn) 
    { 
     roles = rolesIn; 
    } 
} 

ユーザーコントローラ

@Controller @RequestMapping("/user") 
public class UserController 
{ 
    @Autowired private UserService userService; 
    @Autowired private UserDao userDao; 
    @Autowired private RoleDao roleDao; 

    @InitBinder 
    public void bindForm(final WebDataBinder binder) 
    { 
     binder.registerCustomEditor(Set.class, "roles", new CustomFormBinder<RoleDao>(roleDao, Set.class)); 
    } 

    @RequestMapping(method = RequestMethod.GET) 
    public String index(final ModelMap modelMap) 
    { 
     return "/user/index"; 
    } 

    @RequestMapping(value = "/create", method = RequestMethod.GET) 
    public String create(final ModelMap modelMap) 
    { 
     modelMap.addAttribute("userInstance", new User()); 
     modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll())); 

     return "/user/create"; 
    } 

    @RequestMapping(value = "/save", method = RequestMethod.POST) 
    public String save(final ModelMap modelMap, @Valid @ModelAttribute("userInstance") final User user, final BindingResult bindingResult) 
    { 
     // TODO move to service validation 
     if (user.getPassword() == null || !user.getPassword().equals(user.getConfirmPassword())) 
     { 
     bindingResult.addError(new FieldError("userInstance", "password", "password fields must match")); 
     bindingResult.addError(new FieldError("userInstance", "confirmPassword", "password fields must match")); 
     } 
     if (user.getRoles() == null || user.getRoles().isEmpty()) 
     { 
     bindingResult.addError(new FieldError("userInstance", "roles", "Must select at least one role for a User")); 
     } 
     if (bindingResult.hasErrors()) 
     { 
     modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll())); 
     return "/user/create"; 
     } 

     userService.save(user); 
     return "redirect:/user/list"; 
    } 

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) 
    public String edit(@PathVariable final Integer id, final ModelMap modelMap) 
    { 
     final User user = userDao.find(id); 

     if (user != null) 
     { 
     modelMap.addAttribute("userInstance", user); 
     modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll())); 
     return "/user/edit"; 
     } 
     return "redirect:/user/list"; 
    } 

    @RequestMapping(value = "/edit", method = RequestMethod.GET) 
    public String editCurrent(final ModelMap modelMap) 
    { 
     return edit(userService.getLoggedInUser().getId(), modelMap); 
    } 

    @RequestMapping(value = "/update", method = RequestMethod.POST) 
    public String update(@Valid @ModelAttribute("userInstance") final User user, final BindingResult bindingResult) 
    { 
     if (bindingResult.hasErrors()) 
     { 
     return "/user/edit"; 
     } 

     userService.save(user); 
     return "redirect:/user/list"; 
    } 

    @ModelAttribute("userInstances") 
    @RequestMapping(value = "/list", method = RequestMethod.GET) 
    public List<User> list() 
    { 
     return userDao.findAll(); 
    } 
} 

カスタムフォームバインダー

public class CustomFormBinder<T extends GenericDao> extends CustomCollectionEditor 
{ 
    private final T dao; 

    private static final Logger LOG = LoggerFactory.getLogger(CustomFormBinder.class); 

    public CustomFormBinder(final T daoIn, final Class collectionType) 
    { 
     super(collectionType, true); 
     dao = daoIn; 
    } 

    @Override 
    protected Object convertElement(final Object element) 
    { 
     try 
     { 
     // forms should return the id as the itemValue 
     return dao.find(Integer.valueOf(element.toString())); 
     } 
     catch (NumberFormatException e) 
     { 
     LOG.warn("Unable to convert " + element + " to an integer"); 
     return null; 
     } 
    } 

} 

ユーザー編集ビュー

<html> 
    <head> 
     <title>Create User</title> 
    </head> 
    <body> 

    <c:url value="/user/update" var="actionUrl"/> 
    <form:form method="post" commandName="userInstance" action="${actionUrl}"> 
     <h1>Edit User ${userInstance.username}</h1> 

     <div> 
      <form:label path="username">Username:</form:label> 
      <form:input path="username" id="username" readonly="true"/> 
     </div> 

     <div> 
      <form:label path="password">Password:</form:label> 
      <form:input path="password" id="password" type="password" readonly="true"/> 
      <tag:errorlist path="userInstance.password" cssClass="formError"/> 
     </div> 

     <div> 
      <form:label path="firstName">First Name:</form:label> 
      <form:input path="firstName" id="firstName"/> 
      <tag:errorlist path="userInstance.firstName" cssClass="formError"/> 
     </div> 

     <div> 
      <form:label path="lastName">Last Name:</form:label> 
      <form:input path="lastName" id="lastName"/> 
      <tag:errorlist path="userInstance.lastName" cssClass="formError"/> 
     </div> 

     <div> 
      <form:label path="email">Email:</form:label> 
      <form:input path="email" id="email" size="30"/> 
      <tag:errorlist path="userInstance.email" cssClass="formError"/> 
     </div> 

     <div> 
     **<%--Want to Pre Populate these checkboxed--%> 
<form:checkboxes title="Assigned Roles:" path="roles" id="roles" items="${validRoles}" itemLabel="displayName" itemValue="id" element="div"/>** 
      <tag:errorlist path="userInstance.roles" cssClass="formError"/> 
     </div> 

     <form:hidden path="enabled"/> 
     <form:hidden path="id"/> 
     <form:hidden path="version"/> 

     <div class="submit"> 
      <input type="submit" value="Update"/> 
      <a href="<c:url value='/user/list'/>" class="cancel">Cancel</a> 
     </div> 
    </form:form> 

    </body> 
    </html> 
+0

ユーザー$ {userInstance.username}を編集します。

」は、Javaスクリプトの注入を可能にしているようです。 – Ralph

答えて

5

Roleの正しいequalsメソッドが必要です。

これで十分でない場合は、クラスoorg.springframework.web.servlet.tags.form.AbstractCheckedElementTagをご覧ください。メソッドvoid renderFromValue(Object item, Object value, TagWriter tagWriter)は、checkedフラグが設定されている場所です。

+1

equalsメソッドがトリックを実行しました!私はこれをやろうと思っていたとは思っていません。感謝!! – sauce

+0

@ラルフ - 今この問題で問題が発生しています... http://stackoverflow.com/questions/7003152/openentitymanagerinviewfilter-problems...mind見てみましょうか? – sauce

+0

誰かがequalsメソッドの記述方法の例を挙げることができますか?なぜなら、私はEclipseがequalsとhashcode関数を生成するのに使ったが、いくつかの問題があるからです...ありがとう – SaganTheBest

関連する問題