2012-01-02 10 views
13

bağlamak için, ama şu sorunu çözmek için nasıl çözemedim: Bir kullanıcı/rolleri ilişkisi ve bende de yokBahar MVC kullanımı: onay kutusu bu konu etrafında zaten sorular olmuştur biliyorum VERİ

Bir JSP'deki mevcut tüm rolleri, kullanıcıların atandığı onay kutularının bulunduğu onay kutusu öğeleri olarak listelemek istiyorum. Bununla birlikte, eşleşen eşyalar kontrol edilmemiştir (burada, Spring 3.1 kullanıyorum). Kullanıcı nesneden

Özü JSP

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

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

Extract: Yay Denetleyicisi'nden

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

Özü (kullanım nesnesini ve rol listesini Model ekleme)

<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 belgelerinde şu yazıyor: Bağlı değer olduğunda type dizisi veya java.util.Collection öğesinde, bağlı koleksiyonda yapılandırılmış setValue (Object) değeri varsa, input (checkbox) 'checked' olarak işaretlenir.

Buradaki durum bu değil mi? Burada neyi özlüyorum?

Çok teşekkürler.

Paul

cevap

20

Benim tahminim RoleEntity sınıfına üzerinde equals ve hashcode yöntemleri için uygulanmasını eksik olduğunu.

sınır değeri türü dizi ya da java.util.Collection ait giriş (onay kutusu) olarak işaretlenmiş 'kontrol' yapılandırılmış setValue (Obje) değeri bağlı Collection mevcut ise.

Bu doğrudur, ancak equals doğru kurulmadığı hashcode gereken HashSet içinde varlığını kontrol etmek. Bu hat ile

model.addAttribute("roleList", roleList); 

: Hızlı Test işte sorun bu olmadığını görmek için bir o kadar

, bu satırı değiştirin

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

tüm onay kutularını kontrol oluyor mu? Eğer evet ise, o zaman kendi equals ve hashcode vermediniz ve varsayılanlar kullanıldı (Object'dan miras alınanlar).

Varsayılan equals kimliğini karşılaştırır, bu da bir değişkenin başka bir değişkenle aynı örneği tuttuğu anlamına gelir. Eşitlik, iki farklı nesnenin aynı durumu içerdiği veya aynı anlama sahip olduğu anlamına gelir.

model.addAttribute("roleList", userEntity.getRoles()) öğesinin kullanılması, varsayılan equals yönteminin kullanılmasını önler; çünkü listedeki varlığı kontrol ettiğiniz liste ve değerler aynıdır (iki özdeş nesne her zaman eşittir).

Ancak sizin durumunuzda, userEntityService.findById'u bir ve roleEntityService.findAll için ise farklı nesneler anlamına gelir. Bu noktada, kimliğin aksine uygun bir eşitlik testi kullanmalısınız.

equals/hashcode uygulanan var mı? Kodunuzdaki dayanarak

, burada çalışan bir örnektir:

Denetleyici:

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"; 
    } 
} 

Kullanıcı sınıfı:

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; 
    } 
} 

Roller sınıf (ihbar equals ve hashcode yöntemleri; bunları kaldırırsanız örnek artık) çalışır:

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; 
    } 
} 

Görünüm:

<%@ 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> 

dip not JSP'niz hakkında sadece bir gözlem. Formunuz için value="${role}" yaparsanız: onay kutusunu, daha sonra başka bir sorunla karşılaşabileceğiniz value="[email protected]" gibi HTML onay kutusu özniteliklerini alırsınız.

+0

Çok teşekkürler, Bogdan. Bu yanıt gerçekten yardımcı oldu! Ancak, onay kutularını yalnızca kullanıcı rollerini görünümüne eklediğimde kontrol edilir: model.addAttribute ("roleList", userEntity.getRoles()); ama tüm rollerle çalışmıyor. –

+0

@Paul Kuhn: Rica ederim. Cevabı daha iyi yapmak için yorumunuza yanıt olarak birkaç açıklama ekledim. [Burada] (http://tutorials.jenkov.com/java-collections/hashcode-equals.html) daha ayrıntılı bir sunum. Umarım davranışa neyin sebep olduğunu açıklamaya yardımcı olur. – Bogdan