2012-01-02 14 views
13

をバインドするチェックボックス私はすでに、このトピックの周りに質問されているが、私は次の問題を解決する方法を考え出したていない知っていますチェックボックス項目としてJSP内で使用可能なすべてのロールを一覧表示したい場合、チェックボックスが割り当てられているユーザーが選択されます。ただし、一致する項目はチェックされません(ここではSpring 3.1を使用しています)。ユーザオブジェクトからSpring MVCの使用:</p> <p>私は、ユーザー/ロールの関係とIを持っています。データ

エキス:JSPから

UserEntity userEntity = userEntityService.findById(UserEntity.class, new Long(id)); 
model.addAttribute("userAttribute", userEntity); 

List<RoleEntity> roleList = roleEntityService.findAll(); 
model.addAttribute("roleList", roleList); 

エキス:春コントローラから

private Set<RoleEntity> roles = new HashSet<RoleEntity>(); 

抽出物(ユーザオブジェクトとロールリストモデルへの追加)

<form:form modelAttribute="userAttribute" method="POST" action="${saveUrl}"> 
... 

    <table align="center"> 
     <tr> 
      <td>ID</td> 
      <td>Role Name</td> 
     </tr> 
     <c:forEach items="${roleList}" var="role" varStatus="status"> 
      <tr> 
       <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td> 
       <td><c:out value="${role.name}" /></td> 
      </tr> 
     </c:forEach> 
    </table> 

... 
</form:form> 

Spring MVCのドキュメントには、次のように書かれています。 バインドされた値が配列型またはjava.util.Collection型の場合、設定されたsetValue(Object)値がバインドされたCollectionに存在する場合、入力(チェックボックス)は 'checked'としてマークされます。

ここのケースではありませんか?私はここで何が欠けていますか?

ありがとうございます。

ポール

答えて

20

私の推測では、あなたがRoleEntityクラス上equalshashcodeメソッドの実装が欠落しているです。

結合した値が設定のsetValue(オブジェクト)の値がバインドされたコレクション内に存在する場合は「確認」と入力(チェックボックス)がマークされ、型配列またはのjava.util.Collectionです。

これは正しいですが、equalsと正しく実装hashcodeが必要HashSetに存在するかどうかをチェックします。

ただ、それが問題だかどうかを確認するための簡単なテストとして、この行を置き換える:この行で

model.addAttribute("roleList", roleList); 

を:

model.addAttribute("roleList", userEntity.getRoles()); 

は、すべてのチェックボックスをチェックし、あなたのですか?はいの場合は、equalshashcodeを提供せず、デフォルトのものが使用されます(Objectから継承されたもの)。

デフォルトのequalsは、同一のインスタンスが別の変数として保持されていることを意味する同一性を比較します。平等とは、2つの異なるオブジェクトが同じ状態を含むか、同じ意味を持つことを意味します。

model.addAttribute("roleList", userEntity.getRoles())を使用すると、リストので、trueを返すようにデフォルトequalsメソッドをトリガーし、リスト内の存在をチェック値は、(二つの同一のオブジェクトが常に同じである)同じです。

あなたのケースでは、1つはuserEntityService.findById、もう1つはroleEntityService.findAllです。これは異なるオブジェクトを意味します。この時点で、アイデンティティではなく適切な平等テストを使用する必要があります。

equals/hashcodeが実装されていますか?

あなたのコードに基づいて、ここで作品例です。

コントローラー:

import java.util.Arrays; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.List; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

@Controller 
public class SomeController { 
    @RequestMapping(value = "/something", method = { RequestMethod.GET, RequestMethod.POST }) 
    public String handle(Model model) { 

     UserEntity userEntity = new UserEntity(); 
     userEntity.setRoles(new HashSet<RoleEntity>()); 
     Collections.addAll(userEntity.getRoles(), 
           new RoleEntity(1, "one"), 
           new RoleEntity(3, "three")); 
     model.addAttribute("userAttribute", userEntity);   

     List<RoleEntity> roleList = Arrays.asList(
             new RoleEntity(1, "one"), 
             new RoleEntity(2, "two"), 
             new RoleEntity(3, "three") 
            ); 
     model.addAttribute("roleList", roleList); 

     return "view"; 
    } 
} 

Userクラス:

import java.util.HashSet; 
import java.util.Set; 

public class UserEntity { 
    private Set<RoleEntity> roles = new HashSet<RoleEntity>(); 

    public Set<RoleEntity> getRoles() { 
     return roles; 
    } 
    public void setRoles(Set<RoleEntity> roles) { 
     this.roles = roles; 
    } 
} 

役割クラス(予告equalshashcode方法;削除すると、たとえば、もはや作品):

public class RoleEntity { 
    private long id; 
    private String name; 

    @Override 
    public int hashCode() { 
     return new Long(id).hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (! (obj instanceof RoleEntity)) { 
      return false; 
     } 
     return this.id == ((RoleEntity)obj).getId(); 
    } 

    public RoleEntity(long id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    public long getId() { 
     return id; 
    } 
    public void setId(long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

ビュー:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<form:form modelAttribute="userAttribute" method="POST" action="/something"> 
    <table align="center"> 
     <tr> 
      <td>ID</td> 
      <td>Role Name</td> 
     </tr> 
     <c:forEach items="${roleList}" var="role"> 
      <tr> 
       <td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td> 
       <td><c:out value="${role.name}" /></td> 
      </tr> 
     </c:forEach> 
    </table> 
</form:form> 

P.S.あなたのJSPについての一回の観察。フォームにvalue="${role}"を入力した場合:チェックボックスを選択すると、value="[email protected]"などのHTMLチェックボックスの属性が表示され、後で別の問題が発生する可能性があります。

+0

ありがとう、Bogdan。この反応は本当に助けになりました!ただし、チェックボックスは、ビューにユーザーロールを追加した場合にのみチェックされます。model.addAttribute( "roleList"、userEntity.getRoles());すべてのロールでは機能しません。 –

+0

@Paul Kuhn:どうぞよろしくお願いいたします。あなたのコメントに対する回答としていくつかの説明を追加して、回答を改善しました。 [Here](http://tutorials.jenkov.com/java-collections/hashcode-equals.html)は、より詳細なプレゼンテーションです。何がその行動を引き起こしているかをさらに説明するのに役立つといいですね。 – Bogdan

関連する問題

 関連する問題