2012-01-02 1 views
13

를 결합,하지만 나는 다음과 같은 문제를 해결하는 방법을 알아 냈하지 않은 : 나는 사용자/역할 관계와 I를스프링 MVC 사용 : 체크 박스 내가이 주제에 이미 질문이 있었다 알고 데이터를

을 확인란을 지정한 사용자가 선택되는 체크 박스 항목으로 JSP에서 사용 가능한 모든 역할을 나열하려고합니다. 그러나 일치하는 항목은 확인되지 않습니다 (여기에서는 Spring 3.1을 사용하고 있습니다). 사용자 개체에서

추출 다음 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> 

스프링 MVC 문서에서 다음과 같이 말합니다 : 바운드 값이 배열 또는 java.util.Collection 유형의 경우, 구성된 setValue (Object) 값이 바운드 Collection에 있으면 입력 (checkbox)은 'checked'로 표시됩니다.

여기에 해당하지 않습니까? 내가 여기서 무엇을 놓치고 있니?

고마워요.

답변

20

내 생각 엔 당신은 RoleEntity 클래스에 equalshashcode 방법에 대한 구현을 누락 입니다.

바인딩 된 값이 array 또는 java.util.Collection 인 경우 구성된 setValue (Object) 값이 바인딩 된 Collection에 있으면 입력 (checkbox)이 'checked'로 표시됩니다.

이 올바른지,하지만 당신은 equals하고 올바르게 구현 hashcode 필요 HashSet의 존재를 확인 할 수 있습니다. 이 라인

model.addAttribute("roleList", roleList); 

: 빠른 테스트가 문제인지 볼 수있는 것처럼

,이 라인을 교체

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

당신은 모든 체크 박스를 체크받을 수 있나요? 그렇다면 자신의 equalshashcode을 제공하지 않았으며 기본 값 (Object으로부터 상속 된 것)이 사용되었습니다.

기본값 인 equals은 ID가 다른 변수와 동일한 인스턴스를 보유한다는 것을 나타내는 ID를 비교합니다. 평등이란 두 가지 다른 객체가 동일한 상태를 포함하거나 동일한 의미를 갖는 것을 의미합니다.

model.addAttribute("roleList", userEntity.getRoles())을 사용하면 equals 메서드를 트리거하면 목록에 존재 여부를 확인하는 목록과 값이 동일하므로 (두 개의 동일한 개체가 항상 동일 함) 기본값 인 true를 반환합니다.

하지만 귀하의 경우에는 userEntityService.findById (하나는 roleEntityService.findAll, 다른 개체는 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"; 
    } 
} 

사용자 클래스 :

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

관련 문제